mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-12 19:01:55 +00:00
[JITLink][ORC] Add EHFrameRegistrar interface, use in EHFrameRegistrationPlugin.
Replaces direct calls to eh-frame registration with calls to methods on an EHFrameRegistrar instance. This allows clients to substitute a registrar that registers frames in a remote process via IPC/RPC. llvm-svn: 365098
This commit is contained in:
parent
f7e52fbdb5
commit
f5a885fddd
@ -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<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
|
||||
|
@ -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<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;
|
||||
@ -148,9 +153,10 @@ public:
|
||||
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
|
||||
|
@ -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) {
|
||||
|
@ -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<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);
|
||||
@ -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<const void *> EHFrameAddrs = std::move(UntrackedEHFrameAddrs);
|
||||
std::vector<JITTargetAddress> 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;
|
||||
|
@ -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<LocalEHFrameRegistrationPlugin>());
|
||||
ObjLayer.addPlugin(llvm::make_unique<EHFrameRegistrationPlugin>(
|
||||
InProcessEHFrameRegistrar::getInstance()));
|
||||
|
||||
ObjLayer.addPlugin(llvm::make_unique<JITLinkSessionPlugin>(*this));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user