mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-11 23:37:39 +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
f7383bbaa1
commit
07ff51c0a6
@ -27,6 +27,41 @@ Error registerEHFrameSection(const void *EHFrameSectionAddr);
|
|||||||
/// Deregisters all FDEs in the given eh-frame section with the current process.
|
/// Deregisters all FDEs in the given eh-frame section with the current process.
|
||||||
Error deregisterEHFrameSection(const void *EHFrameSectionAddr);
|
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)>;
|
using StoreFrameAddressFunction = std::function<void(JITTargetAddress)>;
|
||||||
|
|
||||||
/// Creates a pass that records the address of the EH frame section. If no
|
/// Creates a pass that records the address of the EH frame section. If no
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
namespace jitlink {
|
||||||
|
class EHFrameRegistrar;
|
||||||
|
} // namespace jitlink
|
||||||
|
|
||||||
namespace object {
|
namespace object {
|
||||||
class ObjectFile;
|
class ObjectFile;
|
||||||
} // namespace object
|
} // namespace object
|
||||||
@ -139,8 +143,9 @@ private:
|
|||||||
std::vector<std::unique_ptr<Plugin>> Plugins;
|
std::vector<std::unique_ptr<Plugin>> Plugins;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LocalEHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
|
class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
|
||||||
public:
|
public:
|
||||||
|
EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
|
||||||
Error notifyEmitted(MaterializationResponsibility &MR) override;
|
Error notifyEmitted(MaterializationResponsibility &MR) override;
|
||||||
void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
|
void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
|
||||||
jitlink::PassConfiguration &PassConfig) override;
|
jitlink::PassConfiguration &PassConfig) override;
|
||||||
@ -148,9 +153,10 @@ public:
|
|||||||
Error notifyRemovingAllModules() override;
|
Error notifyRemovingAllModules() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DenseMap<MaterializationResponsibility *, const void *> InProcessLinks;
|
jitlink::EHFrameRegistrar &Registrar;
|
||||||
DenseMap<VModuleKey, const void *> TrackedEHFrameAddrs;
|
DenseMap<MaterializationResponsibility *, JITTargetAddress> InProcessLinks;
|
||||||
std::vector<const void *> UntrackedEHFrameAddrs;
|
DenseMap<VModuleKey, JITTargetAddress> TrackedEHFrameAddrs;
|
||||||
|
std::vector<JITTargetAddress> UntrackedEHFrameAddrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace orc
|
} // end namespace orc
|
||||||
|
@ -508,6 +508,15 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EHFrameRegistrar::~EHFrameRegistrar() {}
|
||||||
|
|
||||||
|
InProcessEHFrameRegistrar &InProcessEHFrameRegistrar::getInstance() {
|
||||||
|
static InProcessEHFrameRegistrar Instance;
|
||||||
|
return Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
InProcessEHFrameRegistrar::InProcessEHFrameRegistrar() {}
|
||||||
|
|
||||||
AtomGraphPassFunction
|
AtomGraphPassFunction
|
||||||
createEHFrameRecorderPass(const Triple &TT,
|
createEHFrameRecorderPass(const Triple &TT,
|
||||||
StoreFrameAddressFunction StoreFrameAddress) {
|
StoreFrameAddressFunction StoreFrameAddress) {
|
||||||
|
@ -409,7 +409,11 @@ Error ObjectLinkingLayer::removeAllModules() {
|
|||||||
return Err;
|
return Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalEHFrameRegistrationPlugin::modifyPassConfig(
|
EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
|
||||||
|
jitlink::EHFrameRegistrar &Registrar)
|
||||||
|
: Registrar(Registrar) {}
|
||||||
|
|
||||||
|
void EHFrameRegistrationPlugin::modifyPassConfig(
|
||||||
MaterializationResponsibility &MR, const Triple &TT,
|
MaterializationResponsibility &MR, const Triple &TT,
|
||||||
PassConfiguration &PassConfig) {
|
PassConfiguration &PassConfig) {
|
||||||
assert(!InProcessLinks.count(&MR) && "Link for MR already being tracked?");
|
assert(!InProcessLinks.count(&MR) && "Link for MR already being tracked?");
|
||||||
@ -417,18 +421,18 @@ void LocalEHFrameRegistrationPlugin::modifyPassConfig(
|
|||||||
PassConfig.PostFixupPasses.push_back(
|
PassConfig.PostFixupPasses.push_back(
|
||||||
createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr) {
|
createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr) {
|
||||||
if (Addr)
|
if (Addr)
|
||||||
InProcessLinks[&MR] = jitTargetAddressToPointer<void *>(Addr);
|
InProcessLinks[&MR] = Addr;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Error LocalEHFrameRegistrationPlugin::notifyEmitted(
|
Error EHFrameRegistrationPlugin::notifyEmitted(
|
||||||
MaterializationResponsibility &MR) {
|
MaterializationResponsibility &MR) {
|
||||||
|
|
||||||
auto EHFrameAddrItr = InProcessLinks.find(&MR);
|
auto EHFrameAddrItr = InProcessLinks.find(&MR);
|
||||||
if (EHFrameAddrItr == InProcessLinks.end())
|
if (EHFrameAddrItr == InProcessLinks.end())
|
||||||
return Error::success();
|
return Error::success();
|
||||||
|
|
||||||
const void *EHFrameAddr = EHFrameAddrItr->second;
|
auto EHFrameAddr = EHFrameAddrItr->second;
|
||||||
assert(EHFrameAddr && "eh-frame addr to register can not be null");
|
assert(EHFrameAddr && "eh-frame addr to register can not be null");
|
||||||
|
|
||||||
InProcessLinks.erase(EHFrameAddrItr);
|
InProcessLinks.erase(EHFrameAddrItr);
|
||||||
@ -437,25 +441,25 @@ Error LocalEHFrameRegistrationPlugin::notifyEmitted(
|
|||||||
else
|
else
|
||||||
UntrackedEHFrameAddrs.push_back(EHFrameAddr);
|
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);
|
auto EHFrameAddrItr = TrackedEHFrameAddrs.find(K);
|
||||||
if (EHFrameAddrItr == TrackedEHFrameAddrs.end())
|
if (EHFrameAddrItr == TrackedEHFrameAddrs.end())
|
||||||
return Error::success();
|
return Error::success();
|
||||||
|
|
||||||
const void *EHFrameAddr = EHFrameAddrItr->second;
|
auto EHFrameAddr = EHFrameAddrItr->second;
|
||||||
assert(EHFrameAddr && "Tracked eh-frame addr must not be null");
|
assert(EHFrameAddr && "Tracked eh-frame addr must not be null");
|
||||||
|
|
||||||
TrackedEHFrameAddrs.erase(EHFrameAddrItr);
|
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());
|
EHFrameAddrs.reserve(EHFrameAddrs.size() + TrackedEHFrameAddrs.size());
|
||||||
|
|
||||||
for (auto &KV : TrackedEHFrameAddrs)
|
for (auto &KV : TrackedEHFrameAddrs)
|
||||||
@ -466,10 +470,10 @@ Error LocalEHFrameRegistrationPlugin::notifyRemovingAllModules() {
|
|||||||
Error Err = Error::success();
|
Error Err = Error::success();
|
||||||
|
|
||||||
while (!EHFrameAddrs.empty()) {
|
while (!EHFrameAddrs.empty()) {
|
||||||
const void *EHFrameAddr = EHFrameAddrs.back();
|
auto EHFrameAddr = EHFrameAddrs.back();
|
||||||
assert(EHFrameAddr && "Untracked eh-frame addr must not be null");
|
assert(EHFrameAddr && "Untracked eh-frame addr must not be null");
|
||||||
EHFrameAddrs.pop_back();
|
EHFrameAddrs.pop_back();
|
||||||
Err = joinErrors(std::move(Err), deregisterEHFrameSection(EHFrameAddr));
|
Err = joinErrors(std::move(Err), Registrar.deregisterEHFrames(EHFrameAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err;
|
return Err;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "llvm-jitlink.h"
|
#include "llvm-jitlink.h"
|
||||||
|
|
||||||
|
#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCContext.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())
|
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));
|
ObjLayer.addPlugin(llvm::make_unique<JITLinkSessionPlugin>(*this));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user