[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
diff --git a/llvm/tools/lli/RemoteMemoryManager.cpp b/llvm/tools/lli/RemoteMemoryManager.cpp
index 5a135ea..47da8fb 100644
--- a/llvm/tools/lli/RemoteMemoryManager.cpp
+++ b/llvm/tools/lli/RemoteMemoryManager.cpp
@@ -14,7 +14,6 @@
#include "RemoteMemoryManager.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
@@ -78,7 +77,7 @@
}
void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE,
- const ObjectImage *Obj) {
+ const object::ObjectFile &Obj) {
// The client should have called setRemoteTarget() before triggering any
// code generation.
assert(Target);
diff --git a/llvm/tools/lli/RemoteMemoryManager.h b/llvm/tools/lli/RemoteMemoryManager.h
index 0bdb4e2..895bcda 100644
--- a/llvm/tools/lli/RemoteMemoryManager.h
+++ b/llvm/tools/lli/RemoteMemoryManager.h
@@ -80,7 +80,8 @@
// symbols from Modules it contains.
uint64_t getSymbolAddress(const std::string &Name) override { return 0; }
- void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj) override;
+ void notifyObjectLoaded(ExecutionEngine *EE,
+ const object::ObjectFile &Obj) override;
bool finalizeMemory(std::string *ErrMsg) override;
diff --git a/llvm/tools/llvm-jitlistener/llvm-jitlistener.cpp b/llvm/tools/llvm-jitlistener/llvm-jitlistener.cpp
index 0bb6e8b..0f85a85 100644
--- a/llvm/tools/llvm-jitlistener/llvm-jitlistener.cpp
+++ b/llvm/tools/llvm-jitlistener/llvm-jitlistener.cpp
@@ -19,10 +19,10 @@
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/MCJIT.h"
-#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
index 87d381e..c38e423 100644
--- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -13,8 +13,6 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/ExecutionEngine/ObjectBuffer.h"
-#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -207,23 +205,32 @@
if (std::error_code EC = InputBuffer.getError())
return Error("unable to read input: '" + EC.message() + "'");
- std::unique_ptr<ObjectImage> LoadedObject;
+ ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
+ ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
+
+ if (std::error_code EC = MaybeObj.getError())
+ return Error("unable to create object file: '" + EC.message() + "'");
+
+ ObjectFile &Obj = **MaybeObj;
+
// Load the object file
- LoadedObject = Dyld.loadObject(
- llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
- if (!LoadedObject) {
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo =
+ Dyld.loadObject(Obj);
+
+ if (Dyld.hasError())
return Error(Dyld.getErrorString());
- }
// Resolve all the relocations we can.
Dyld.resolveRelocations();
+ OwningBinary<ObjectFile> DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
+
std::unique_ptr<DIContext> Context(
- DIContext::getDWARFContext(*LoadedObject->getObjectFile()));
+ DIContext::getDWARFContext(*DebugObj.getBinary()));
// Use symbol info to iterate functions in the object.
- for (object::symbol_iterator I = LoadedObject->begin_symbols(),
- E = LoadedObject->end_symbols();
+ for (object::symbol_iterator I = DebugObj.getBinary()->symbol_begin(),
+ E = DebugObj.getBinary()->symbol_end();
I != E; ++I) {
object::SymbolRef::Type SymType;
if (I->getType(SymType)) continue;
@@ -268,11 +275,17 @@
MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
if (std::error_code EC = InputBuffer.getError())
return Error("unable to read input: '" + EC.message() + "'");
- std::unique_ptr<ObjectImage> LoadedObject;
+ ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
+ ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
+
+ if (std::error_code EC = MaybeObj.getError())
+ return Error("unable to create object file: '" + EC.message() + "'");
+
+ ObjectFile &Obj = **MaybeObj;
+
// Load the object file
- LoadedObject = Dyld.loadObject(
- llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
- if (!LoadedObject) {
+ Dyld.loadObject(Obj);
+ if (Dyld.hasError()) {
return Error(Dyld.getErrorString());
}
}
@@ -512,14 +525,21 @@
// Load the input memory buffer.
ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
+
if (std::error_code EC = InputBuffer.getError())
return Error("unable to read input: '" + EC.message() + "'");
- std::unique_ptr<ObjectImage> LoadedObject;
+ ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
+ ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
+
+ if (std::error_code EC = MaybeObj.getError())
+ return Error("unable to create object file: '" + EC.message() + "'");
+
+ ObjectFile &Obj = **MaybeObj;
+
// Load the object file
- LoadedObject = Dyld.loadObject(
- llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
- if (!LoadedObject) {
+ Dyld.loadObject(Obj);
+ if (Dyld.hasError()) {
return Error(Dyld.getErrorString());
}
}