From 829a19ae74c572bdb5e46b4e4b85a35503255c94 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 26 Nov 2014 06:53:26 +0000 Subject: [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 --- .../IntelJITEvents/IntelJITEventListener.cpp | 40 +++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'llvm/lib/ExecutionEngine/IntelJITEvents') 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 ObjectMap; ObjectMap LoadedObjectMap; + std::map> 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 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 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. -- cgit v1.2.3