summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2017-05-09 21:32:18 +0000
committerLang Hames <lhames@gmail.com>2017-05-09 21:32:18 +0000
commitc936ac7f37dc5a801fdffcb97076244b7a649540 (patch)
treeb1ee05b6df38ca85ad75237375c7969324d0d90e /llvm/include
parent29405c94e61f17323a3af1af7f8f64d64b7e11a7 (diff)
downloadbcm5719-llvm-c936ac7f37dc5a801fdffcb97076244b7a649540.tar.gz
bcm5719-llvm-c936ac7f37dc5a801fdffcb97076244b7a649540.zip
[ExecutionEngine] Make RuntimeDyld::MemoryManager responsible for tracking EH
frames. RuntimeDyld was previously responsible for tracking allocated EH frames, but it makes more sense to have the RuntimeDyld::MemoryManager track them (since the frames are allocated through the memory manager, and written to memory owned by the memory manager). This patch moves the frame tracking into RTDyldMemoryManager, and changes the deregisterFrames method on RuntimeDyld::MemoryManager from: void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size); to: void deregisterEHFrames(); Separating this responsibility will allow ORC to continue to throw the RuntimeDyld instances away post-link (saving a few dozen bytes per lazy function) while properly deregistering frames when modules are unloaded. This patch also updates ORC to call deregisterEHFrames when modules are unloaded. This fixes a bug where an exception that tears down the JIT can then unwind through dangling EH frames that have been deallocated but not deregistered, resulting in UB. For people using SectionMemoryManager this should be pretty much a no-op. For people with custom allocators that override registerEHFrames/deregisterEHFrames, you will now be responsible for tracking allocated EH frames. Reviewed in https://reviews.llvm.org/D32829 llvm-svn: 302589
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h13
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h29
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h4
-rw-r--r--llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h16
-rw-r--r--llvm/include/llvm/ExecutionEngine/RuntimeDyld.h3
5 files changed, 45 insertions, 20 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 7e7f7358938..1bb911d09cf 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -172,6 +172,11 @@ private:
return nullptr;
}
+ void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
+ for (auto &BLH : BaseLayerHandles)
+ BaseLayer.removeModuleSet(BLH);
+ }
+
std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver;
std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
@@ -204,6 +209,11 @@ public:
CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
+ ~CompileOnDemandLayer() {
+ while (!LogicalDylibs.empty())
+ removeModuleSet(LogicalDylibs.begin());
+ }
+
/// @brief Add a module to the compile-on-demand layer.
template <typename ModuleSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
@@ -239,6 +249,7 @@ public:
/// This will remove all modules in the layers below that were derived from
/// the module represented by H.
void removeModuleSet(ModuleSetHandleT H) {
+ H->removeModulesFromBaseLayer(BaseLayer);
LogicalDylibs.erase(H);
}
@@ -478,6 +489,8 @@ private:
return 0;
}
+ LD.BaseLayerHandles.push_back(PartH);
+
return CalledAddr;
}
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
index 02f59d6a831..a19c30631c5 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
@@ -144,16 +144,16 @@ public:
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) override {
- UnfinalizedEHFrames.push_back(
- std::make_pair(LoadAddr, static_cast<uint32_t>(Size)));
+ UnfinalizedEHFrames.push_back({LoadAddr, Size});
}
- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
- size_t Size) override {
- auto Err = Client.deregisterEHFrames(LoadAddr, Size);
- // FIXME: Add error poll.
- assert(!Err && "Failed to register remote EH frames.");
- (void)Err;
+ void deregisterEHFrames() override {
+ for (auto &Frame : RegisteredEHFrames) {
+ auto Err = Client.deregisterEHFrames(Frame.Addr, Frame.Size);
+ // FIXME: Add error poll.
+ assert(!Err && "Failed to register remote EH frames.");
+ (void)Err;
+ }
}
void notifyObjectLoaded(RuntimeDyld &Dyld,
@@ -320,7 +320,7 @@ public:
Unfinalized.clear();
for (auto &EHFrame : UnfinalizedEHFrames) {
- if (auto Err = Client.registerEHFrames(EHFrame.first, EHFrame.second)) {
+ if (auto Err = Client.registerEHFrames(EHFrame.Addr, EHFrame.Size)) {
// FIXME: Replace this once finalizeMemory can return an Error.
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
if (ErrMsg) {
@@ -331,7 +331,8 @@ public:
return false;
}
}
- UnfinalizedEHFrames.clear();
+ RegisteredEHFrames = std::move(UnfinalizedEHFrames);
+ UnfinalizedEHFrames = {};
return false;
}
@@ -387,7 +388,13 @@ public:
ResourceIdMgr::ResourceId Id;
std::vector<ObjectAllocs> Unmapped;
std::vector<ObjectAllocs> Unfinalized;
- std::vector<std::pair<uint64_t, uint32_t>> UnfinalizedEHFrames;
+
+ struct EHFrame {
+ JITTargetAddress Addr;
+ uint64_t Size;
+ };
+ std::vector<EHFrame> UnfinalizedEHFrames;
+ std::vector<EHFrame> RegisteredEHFrames;
};
/// Remote indirect stubs manager.
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index babcc7f26aa..5b3426afe58 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -120,6 +120,10 @@ private:
buildInitialSymbolTable(PFC->Objects);
}
+ ~ConcreteLinkedObjectSet() override {
+ MemMgr->deregisterEHFrames();
+ }
+
void setHandle(ObjSetHandleT H) {
PFC->Handle = H;
}
diff --git a/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
index 5638717790b..74535fe948f 100644
--- a/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
+++ b/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
@@ -69,13 +69,8 @@ public:
/// Deregister EH frames in the current proces.
static void deregisterEHFramesInProcess(uint8_t *Addr, size_t Size);
- void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
- registerEHFramesInProcess(Addr, Size);
- }
-
- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
- deregisterEHFramesInProcess(Addr, Size);
- }
+ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
+ void deregisterEHFrames() override;
/// This method returns the address of the specified function or variable in
/// the current process.
@@ -139,6 +134,13 @@ public:
/// MCJIT or RuntimeDyld. Use getSymbolAddress instead.
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
+
+private:
+ struct EHFrame {
+ uint8_t *Addr;
+ size_t Size;
+ };
+ std::vector<EHFrame> EHFrames;
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
index 13a5f9922c5..9470866dc0d 100644
--- a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -150,8 +150,7 @@ public:
/// be the case for local execution) these two values will be the same.
virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) = 0;
- virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr,
- size_t Size) = 0;
+ virtual void deregisterEHFrames() = 0;
/// This method is called when object loading is complete and section page
/// permissions can be applied. It is up to the memory manager implementation
OpenPOWER on IntegriCloud