/// 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<void *>(EHFrameSectionAddr));
+ }
+
+ Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr) override {
+ return deregisterEHFrameSection(
+ jitTargetAddressToPointer<void *>(EHFrameSectionAddr));
+ }
+
+private:
+ InProcessEHFrameRegistrar();
+};
+
using StoreFrameAddressFunction = std::function<void(JITTargetAddress)>;
/// Creates a pass that records the address of the EH frame section. If no
namespace llvm {
+namespace jitlink {
+class EHFrameRegistrar;
+} // namespace jitlink
+
namespace object {
class ObjectFile;
} // namespace object
std::vector<std::unique_ptr<Plugin>> 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;
Error notifyRemovingAllModules() override;
private:
- DenseMap<MaterializationResponsibility *, const void *> InProcessLinks;
- DenseMap<VModuleKey, const void *> TrackedEHFrameAddrs;
- std::vector<const void *> UntrackedEHFrameAddrs;
+ jitlink::EHFrameRegistrar &Registrar;
+ DenseMap<MaterializationResponsibility *, JITTargetAddress> InProcessLinks;
+ DenseMap<VModuleKey, JITTargetAddress> TrackedEHFrameAddrs;
+ std::vector<JITTargetAddress> UntrackedEHFrameAddrs;
};
} // end namespace orc
#endif
}
+EHFrameRegistrar::~EHFrameRegistrar() {}
+
+InProcessEHFrameRegistrar &InProcessEHFrameRegistrar::getInstance() {
+ static InProcessEHFrameRegistrar Instance;
+ return Instance;
+}
+
+InProcessEHFrameRegistrar::InProcessEHFrameRegistrar() {}
+
AtomGraphPassFunction
createEHFrameRecorderPass(const Triple &TT,
StoreFrameAddressFunction StoreFrameAddress) {
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?");
PassConfig.PostFixupPasses.push_back(
createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr) {
if (Addr)
- InProcessLinks[&MR] = jitTargetAddressToPointer<void *>(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);
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<const void *> EHFrameAddrs = std::move(UntrackedEHFrameAddrs);
+ std::vector<JITTargetAddress> EHFrameAddrs = std::move(UntrackedEHFrameAddrs);
EHFrameAddrs.reserve(EHFrameAddrs.size() + TrackedEHFrameAddrs.size());
for (auto &KV : TrackedEHFrameAddrs)
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;
#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"
};
if (!NoExec && !TT.isOSWindows())
- ObjLayer.addPlugin(llvm::make_unique<LocalEHFrameRegistrationPlugin>());
+ ObjLayer.addPlugin(llvm::make_unique<EHFrameRegistrationPlugin>(
+ InProcessEHFrameRegistrar::getInstance()));
ObjLayer.addPlugin(llvm::make_unique<JITLinkSessionPlugin>(*this));
}