diff options
author | Lang Hames <lhames@gmail.com> | 2014-11-26 06:53:26 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2014-11-26 06:53:26 +0000 |
commit | 829a19ae74c572bdb5e46b4e4b85a35503255c94 (patch) | |
tree | b1eac9db4b702227031bb68af4ee1b9b34b256ce /llvm/lib/ExecutionEngine/IntelJITEvents | |
parent | bf82611bc8fa3d384a2a73cbfc898cf67db5edd7 (diff) | |
download | bcm5719-llvm-829a19ae74c572bdb5e46b4e4b85a35503255c94.tar.gz bcm5719-llvm-829a19ae74c572bdb5e46b4e4b85a35503255c94.zip |
[MCJIT] Clean up RuntimeDyld's quirky object-ownership/modification scheme.
Previously, when loading an object file, RuntimeDyld (1) took ownership of the
ObjectFile instance (and associated MemoryBuffer), (2) potentially modified the
object in-place, and (3) returned an ObjectImage that managed ownership of the
now-modified object and provided some convenience methods. This scheme accreted
over several years as features were tacked on to RuntimeDyld, and was both
unintuitive and unsafe (See e.g. http://llvm.org/PR20722).
This patch fixes the issue by removing all ownership and in-place modification
of object files from RuntimeDyld. Existing behavior, including debugger
registration, is preserved.
Noteworthy changes include:
(1) ObjectFile instances are now passed to RuntimeDyld by const-ref.
(2) The ObjectImage and ObjectBuffer classes have been removed entirely, they
existed to model ownership within RuntimeDyld, and so are no longer needed.
(3) RuntimeDyld::loadObject now returns an instance of a new class,
RuntimeDyld::LoadedObjectInfo, which can be used to construct a modified
object suitable for registration with the debugger, following the existing
debugger registration scheme.
(4) The JITRegistrar class has been removed, and the GDBRegistrar class has been
re-written as a JITEventListener.
This should fix http://llvm.org/PR20722 .
llvm-svn: 222810
Diffstat (limited to 'llvm/lib/ExecutionEngine/IntelJITEvents')
-rw-r--r-- | llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index b23ca88baf1..c35e5244ecd 100644 --- a/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -21,7 +21,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/DebugInfo/DIContext.h" -#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -32,6 +31,7 @@ using namespace llvm; using namespace llvm::jitprofiling; +using namespace llvm::object; #define DEBUG_TYPE "amplifier-jit-event-listener" @@ -48,6 +48,7 @@ class IntelJITEventListener : public JITEventListener { typedef DenseMap<const void *, MethodAddressVector> ObjectMap; ObjectMap LoadedObjectMap; + std::map<const char*, OwningBinary<ObjectFile>> DebugObjects; public: IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) { @@ -57,9 +58,10 @@ public: ~IntelJITEventListener() { } - virtual void NotifyObjectEmitted(const ObjectImage &Obj); + void NotifyObjectEmitted(const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) override; - virtual void NotifyFreeingObject(const ObjectImage &Obj); + void NotifyFreeingObject(const ObjectFile &Obj) override; }; static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress, @@ -95,23 +97,29 @@ static iJIT_Method_Load FunctionDescToIntelJITFormat( return Result; } -void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) { +void IntelJITEventListener::NotifyObjectEmitted( + const ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &L) { + + OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj); + const ObjectFile &DebugObj = *DebugObjOwner.getBinary(); + // Get the address of the object image for use as a unique identifier - const void* ObjData = Obj.getData().data(); - DIContext* Context = DIContext::getDWARFContext(*Obj.getObjectFile()); + const void* ObjData = DebugObj.getData().data(); + DIContext* Context = DIContext::getDWARFContext(DebugObj); MethodAddressVector Functions; // Use symbol info to iterate functions in the object. - for (object::symbol_iterator I = Obj.begin_symbols(), - E = Obj.end_symbols(); + for (symbol_iterator I = DebugObj.symbol_begin(), + E = DebugObj.symbol_end(); I != E; ++I) { std::vector<LineNumberInfo> LineInfo; std::string SourceFileName; - object::SymbolRef::Type SymType; + SymbolRef::Type SymType; if (I->getType(SymType)) continue; - if (SymType == object::SymbolRef::ST_Function) { + if (SymType == SymbolRef::ST_Function) { StringRef Name; uint64_t Addr; uint64_t Size; @@ -162,11 +170,18 @@ void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) { // registered function addresses for each loaded object. We will // use the MethodIDs map to get the registered ID for each function. LoadedObjectMap[ObjData] = Functions; + DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner); } -void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) { +void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { + // This object may not have been registered with the listener. If it wasn't, + // bail out. + if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end()) + return; + // Get the address of the object image for use as a unique identifier - const void* ObjData = Obj.getData().data(); + const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary(); + const void* ObjData = DebugObj.getData().data(); // Get the object's function list from LoadedObjectMap ObjectMap::iterator OI = LoadedObjectMap.find(ObjData); @@ -190,6 +205,7 @@ void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) { // Erase the object from LoadedObjectMap LoadedObjectMap.erase(OI); + DebugObjects.erase(Obj.getData().data()); } } // anonymous namespace. |