aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/ExecutionEngine/ObjectBuffer.h80
-rw-r--r--include/llvm/ExecutionEngine/ObjectImage.h61
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h10
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.cpp30
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.h9
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp8
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h6
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (renamed from lib/ExecutionEngine/RuntimeDyld/ObjectImage.h)135
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp16
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp77
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h9
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h17
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp6
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h2
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp8
15 files changed, 311 insertions, 163 deletions
diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
new file mode 100644
index 0000000..a0a77b8
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectBuffer.h
@@ -0,0 +1,80 @@
+//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a wrapper class to hold the memory into which an
+// object will be generated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+namespace llvm {
+
+/// ObjectBuffer - This class acts as a container for the memory buffer used during
+/// generation and loading of executable objects using MCJIT and RuntimeDyld. The
+/// underlying memory for the object will be owned by the ObjectBuffer instance
+/// throughout its lifetime. The getMemBuffer() method provides a way to create a
+/// MemoryBuffer wrapper object instance to be owned by other classes (such as
+/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the
+/// actual memory it points to.
+class ObjectBuffer {
+public:
+ ObjectBuffer() {}
+ ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {}
+ virtual ~ObjectBuffer() {}
+
+ /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function
+ /// returns a pointer to an object that is owned by the caller. However,
+ /// the caller does not take ownership of the underlying memory.
+ MemoryBuffer *getMemBuffer() const {
+ return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), "", false);
+ }
+
+ const char *getBufferStart() const { return Buffer->getBufferStart(); }
+ size_t getBufferSize() const { return Buffer->getBufferSize(); }
+
+protected:
+ // The memory contained in an ObjectBuffer
+ OwningPtr<MemoryBuffer> Buffer;
+};
+
+/// ObjectBufferStream - This class encapsulates the SmallVector and
+/// raw_svector_ostream needed to generate an object using MC code emission
+/// while providing a common ObjectBuffer interface for access to the
+/// memory once the object has been generated.
+class ObjectBufferStream : public ObjectBuffer {
+public:
+ ObjectBufferStream() : OS(SV) {}
+ virtual ~ObjectBufferStream() {}
+
+ raw_ostream &getOStream() { return OS; }
+ void flush()
+ {
+ OS.flush();
+
+ // Make the data accessible via the ObjectBuffer::Buffer
+ Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()),
+ "",
+ false));
+ }
+
+protected:
+ SmallVector<char, 4096> SV; // Working buffer into which we JIT.
+ raw_svector_ostream OS; // streaming wrapper
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h
new file mode 100644
index 0000000..82549ad
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectImage.h
@@ -0,0 +1,61 @@
+//===---- ObjectImage.h - Format independent executuable object image -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectImage class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+
+namespace llvm {
+
+
+/// ObjectImage - A container class that represents an ObjectFile that has been
+/// or is in the process of being loaded into memory for execution.
+class ObjectImage {
+ ObjectImage() LLVM_DELETED_FUNCTION;
+ ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
+
+protected:
+ OwningPtr<ObjectBuffer> Buffer;
+
+public:
+ ObjectImage(ObjectBuffer *Input) : Buffer(Input) {}
+ virtual ~ObjectImage() {}
+
+ virtual object::symbol_iterator begin_symbols() const = 0;
+ virtual object::symbol_iterator end_symbols() const = 0;
+
+ virtual object::section_iterator begin_sections() const = 0;
+ virtual object::section_iterator end_sections() const = 0;
+
+ virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+ // Subclasses can override these methods to update the image with loaded
+ // addresses for sections and common symbols
+ virtual void updateSectionAddress(const object::SectionRef &Sec,
+ uint64_t Addr) = 0;
+ virtual void updateSymbolAddress(const object::SymbolRef &Sym,
+ uint64_t Addr) = 0;
+
+ virtual StringRef getData() const = 0;
+
+ // Subclasses can override these methods to provide JIT debugging support
+ virtual void registerWithDebugger() = 0;
+ virtual void deregisterWithDebugger() = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
+
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index a02cbe2..7da4a4e 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -15,12 +15,13 @@
#define LLVM_RUNTIME_DYLD_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/Support/Memory.h"
namespace llvm {
class RuntimeDyldImpl;
-class MemoryBuffer;
+class ObjectImage;
// RuntimeDyld clients often want to handle the memory management of
// what gets placed where. For JIT clients, this is an abstraction layer
@@ -65,8 +66,11 @@ public:
RuntimeDyld(RTDyldMemoryManager*);
~RuntimeDyld();
- /// Load an in-memory object file into the dynamic linker.
- bool loadObject(MemoryBuffer *InputBuffer);
+ /// loadObject - prepare the object contained in the input buffer for
+ /// execution. Ownership of the input buffer is transferred to the
+ /// ObjectImage instance returned from this function if successful.
+ /// In the case of load failure, the input buffer will be deleted.
+ ObjectImage *loadObject(ObjectBuffer *InputBuffer);
/// Get the address of our local copy of the symbol. This may or may not
/// be the address used for relocation (clients can copy the data around
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index fa71305..15cbae9 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -12,8 +12,10 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DynamicLibrary.h"
@@ -50,7 +52,7 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM,
bool AllocateGVsWithCode)
: ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM),
- isCompiled(false), M(m), OS(Buffer) {
+ isCompiled(false), M(m) {
setTargetData(TM->getTargetData());
}
@@ -63,7 +65,7 @@ MCJIT::~MCJIT() {
void MCJIT::emitObject(Module *m) {
/// Currently, MCJIT only supports a single module and the module passed to
/// this function call is expected to be the contained module. The module
- /// is passed as a parameter here to prepare for multiple module support in
+ /// is passed as a parameter here to prepare for multiple module support in
/// the future.
assert(M == m);
@@ -80,30 +82,32 @@ void MCJIT::emitObject(Module *m) {
PM.add(new TargetData(*TM->getTargetData()));
+ // The RuntimeDyld will take ownership of this shortly
+ OwningPtr<ObjectBufferStream> Buffer(new ObjectBufferStream());
+
// Turn the machine code intermediate representation into bytes in memory
// that may be executed.
- if (TM->addPassesToEmitMC(PM, Ctx, OS, false)) {
+ if (TM->addPassesToEmitMC(PM, Ctx, Buffer->getOStream(), false)) {
report_fatal_error("Target does not support MC emission!");
}
// Initialize passes.
- // FIXME: When we support multiple modules, we'll want to move the code
- // gen and finalization out of the constructor here and do it more
- // on-demand as part of getPointerToFunction().
PM.run(*m);
- // Flush the output buffer so the SmallVector gets its data.
- OS.flush();
+ // Flush the output buffer to get the generated code into memory
+ Buffer->flush();
// Load the object into the dynamic linker.
- MemoryBuffer* MB = MemoryBuffer::getMemBuffer(StringRef(Buffer.data(),
- Buffer.size()),
- "", false);
- if (Dyld.loadObject(MB))
+ // handing off ownership of the buffer
+ LoadedObject.reset(Dyld.loadObject(Buffer.take()));
+ if (!LoadedObject)
report_fatal_error(Dyld.getErrorString());
// Resolve any relocations.
Dyld.resolveRelocations();
+ // FIXME: Make this optional, maybe even move it to a JIT event listener
+ LoadedObject->registerWithDebugger();
+
// FIXME: Add support for per-module compilation state
isCompiled = true;
}
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h
index d5c5d77..b9ff06e 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -13,11 +13,11 @@
#include "llvm/PassManager.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/raw_ostream.h"
namespace llvm {
+class ObjectImage;
+
// FIXME: This makes all kinds of horrible assumptions for the time being,
// like only having one module, not needing to worry about multi-threading,
// blah blah. Purely in get-it-up-and-limping mode for now.
@@ -34,10 +34,7 @@ class MCJIT : public ExecutionEngine {
// FIXME: Add support for multiple modules
bool isCompiled;
Module *M;
-
- // FIXME: Move these to a single container which manages JITed objects
- SmallVector<char, 4096> Buffer; // Working buffer into which we JIT.
- raw_svector_ostream OS;
+ OwningPtr<ObjectImage> LoadedObject;
public:
~MCJIT();
diff --git a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
index 8b50101..50cd072 100644
--- a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
@@ -78,12 +78,12 @@ public:
/// Creates an entry in the JIT registry for the buffer @p Object,
/// which must contain an object file in executable memory with any
/// debug information for the debugger.
- void registerObject(const MemoryBuffer &Object);
+ void registerObject(const ObjectBuffer &Object);
/// Removes the internal registration of @p Object, and
/// frees associated resources.
/// Returns true if @p Object was found in ObjectBufferMap.
- bool deregisterObject(const MemoryBuffer &Object);
+ bool deregisterObject(const ObjectBuffer &Object);
private:
/// Deregister the debug info for the given object file from the debugger
@@ -124,7 +124,7 @@ GDBJITRegistrar::~GDBJITRegistrar() {
ObjectBufferMap.clear();
}
-void GDBJITRegistrar::registerObject(const MemoryBuffer &Object) {
+void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) {
const char *Buffer = Object.getBufferStart();
size_t Size = Object.getBufferSize();
@@ -147,7 +147,7 @@ void GDBJITRegistrar::registerObject(const MemoryBuffer &Object) {
}
}
-bool GDBJITRegistrar::deregisterObject(const MemoryBuffer& Object) {
+bool GDBJITRegistrar::deregisterObject(const ObjectBuffer& Object) {
const char *Buffer = Object.getBufferStart();
RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer);
diff --git a/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h b/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
index f964bc6..69e9dbe 100644
--- a/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
+++ b/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
@@ -10,7 +10,7 @@
#ifndef LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H
#define LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
namespace llvm {
@@ -27,12 +27,12 @@ public:
/// Creates an entry in the JIT registry for the buffer @p Object,
/// which must contain an object file in executable memory with any
/// debug information for the debugger.
- virtual void registerObject(const MemoryBuffer &Object) = 0;
+ virtual void registerObject(const ObjectBuffer &Object) = 0;
/// Removes the internal registration of @p Object, and
/// frees associated resources.
/// Returns true if @p Object was previously registered.
- virtual bool deregisterObject(const MemoryBuffer &Object) = 0;
+ virtual bool deregisterObject(const ObjectBuffer &Object) = 0;
/// Returns a reference to a GDB JIT registrar singleton
static JITRegistrar& getGDBRegistrar();
diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
index 4fa5c1c..17f3a21 100644
--- a/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h
+++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
@@ -1,59 +1,76 @@
-//===---- ObjectImage.h - Format independent executuable object image -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares a file format independent ObjectImage class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-#define LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-
-#include "llvm/Object/ObjectFile.h"
-
-namespace llvm {
-
-class ObjectImage {
- ObjectImage() LLVM_DELETED_FUNCTION;
- ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
-protected:
- object::ObjectFile *ObjFile;
-
-public:
- ObjectImage(object::ObjectFile *Obj) { ObjFile = Obj; }
- virtual ~ObjectImage() {}
-
- virtual object::symbol_iterator begin_symbols() const
- { return ObjFile->begin_symbols(); }
- virtual object::symbol_iterator end_symbols() const
- { return ObjFile->end_symbols(); }
-
- virtual object::section_iterator begin_sections() const
- { return ObjFile->begin_sections(); }
- virtual object::section_iterator end_sections() const
- { return ObjFile->end_sections(); }
-
- virtual /* Triple::ArchType */ unsigned getArch() const
- { return ObjFile->getArch(); }
-
- // Subclasses can override these methods to update the image with loaded
- // addresses for sections and common symbols
- virtual void updateSectionAddress(const object::SectionRef &Sec,
- uint64_t Addr) {}
- virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr)
- {}
-
- // Subclasses can override these methods to provide JIT debugging support
- virtual void registerWithDebugger() {}
- virtual void deregisterWithDebugger() {}
-};
-
-} // end namespace llvm
-
-#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-
+//===-- ObjectImageCommon.h - Format independent executuable object image -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectImage class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
+#define LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+
+namespace llvm {
+
+class ObjectImageCommon : public ObjectImage {
+ ObjectImageCommon(); // = delete
+ ObjectImageCommon(const ObjectImageCommon &other); // = delete
+
+protected:
+ object::ObjectFile *ObjFile;
+
+ // This form of the constructor allows subclasses to use
+ // format-specific subclasses of ObjectFile directly
+ ObjectImageCommon(ObjectBuffer *Input, object::ObjectFile *Obj)
+ : ObjectImage(Input), // saves Input as Buffer and takes ownership
+ ObjFile(Obj)
+ {
+ }
+
+public:
+ ObjectImageCommon(ObjectBuffer* Input)
+ : ObjectImage(Input) // saves Input as Buffer and takes ownership
+ {
+ ObjFile = object::ObjectFile::createObjectFile(Buffer->getMemBuffer());
+ }
+ virtual ~ObjectImageCommon() { delete ObjFile; }
+
+ virtual object::symbol_iterator begin_symbols() const
+ { return ObjFile->begin_symbols(); }
+ virtual object::symbol_iterator end_symbols() const
+ { return ObjFile->end_symbols(); }
+
+ virtual object::section_iterator begin_sections() const
+ { return ObjFile->begin_sections(); }
+ virtual object::section_iterator end_sections() const
+ { return ObjFile->end_sections(); }
+
+ virtual /* Triple::ArchType */ unsigned getArch() const
+ { return ObjFile->getArch(); }
+
+ virtual StringRef getData() const { return ObjFile->getData(); }
+
+ // Subclasses can override these methods to update the image with loaded
+ // addresses for sections and common symbols
+ virtual void updateSectionAddress(const object::SectionRef &Sec,
+ uint64_t Addr) {}
+ virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr)
+ {}
+
+ // Subclasses can override these methods to provide JIT debugging support
+ virtual void registerWithDebugger() {}
+ virtual void deregisterWithDebugger() {}
+};
+
+} // end namespace llvm
+
+#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
+
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index d06a1fc..eb69693 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "dyld"
+#include "ObjectImageCommon.h"
#include "RuntimeDyldImpl.h"
#include "RuntimeDyldELF.h"
#include "RuntimeDyldMachO.h"
@@ -61,14 +62,11 @@ void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress,
// Subclasses can implement this method to create specialized image instances.
// The caller owns the pointer that is returned.
-ObjectImage *RuntimeDyldImpl::createObjectImage(const MemoryBuffer *InputBuffer) {
- ObjectFile *ObjFile = ObjectFile::createObjectFile(const_cast<MemoryBuffer*>
- (InputBuffer));
- ObjectImage *Obj = new ObjectImage(ObjFile);
- return Obj;
+ObjectImage *RuntimeDyldImpl::createObjectImage(ObjectBuffer *InputBuffer) {
+ return new ObjectImageCommon(InputBuffer);
}
-bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
+ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) {
OwningPtr<ObjectImage> obj(createObjectImage(InputBuffer));
if (!obj)
report_fatal_error("Unable to create object image from memory buffer!");
@@ -178,9 +176,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
}
}
- handleObjectLoaded(obj.take());
-
- return false;
+ return obj.take();
}
void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
@@ -437,7 +433,7 @@ RuntimeDyld::~RuntimeDyld() {
delete Dyld;
}
-bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
+ObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) {
if (!Dyld) {
sys::LLVMFileType type = sys::IdentifyFileType(
InputBuffer->getBufferStart(),
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index a1c0e40..597c5cb 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -12,16 +12,19 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "dyld"
+#include "RuntimeDyldELF.h"
+#include "JITRegistrar.h"
+#include "ObjectImageCommon.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/IntervalMap.h"
-#include "RuntimeDyldELF.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/Support/ELF.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Object/ELF.h"
-#include "JITRegistrar.h"
using namespace llvm;
using namespace llvm::object;
@@ -41,19 +44,12 @@ class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> {
typedef typename ELFDataTypeTypedefHelper<
target_endianness, is64Bits>::value_type addr_type;
-protected:
- // This duplicates the 'Data' member in the 'Binary' base class
- // but it is necessary to workaround a bug in gcc 4.2
- MemoryBuffer *InputData;
-
public:
- DyldELFObject(MemoryBuffer *Object, error_code &ec);
+ DyldELFObject(MemoryBuffer *Wrapper, error_code &ec);
void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr);
- const MemoryBuffer& getBuffer() const { return *InputData; }
-
// Methods for type inquiry through isa, cast and dyn_cast
static inline bool classof(const Binary *v) {
return (isa<ELFObjectFile<target_endianness, is64Bits> >(v)
@@ -69,14 +65,15 @@ public:
};
template<support::endianness target_endianness, bool is64Bits>
-class ELFObjectImage : public ObjectImage {
+class ELFObjectImage : public ObjectImageCommon {
protected:
DyldELFObject<target_endianness, is64Bits> *DyldObj;
bool Registered;
public:
- ELFObjectImage(DyldELFObject<target_endianness, is64Bits> *Obj)
- : ObjectImage(Obj),
+ ELFObjectImage(ObjectBuffer *Input,
+ DyldELFObject<target_endianness, is64Bits> *Obj)
+ : ObjectImageCommon(Input, Obj),
DyldObj(Obj),
Registered(false) {}
@@ -99,20 +96,22 @@ class ELFObjectImage : public ObjectImage {
virtual void registerWithDebugger()
{
- JITRegistrar::getGDBRegistrar().registerObject(DyldObj->getBuffer());
+ JITRegistrar::getGDBRegistrar().registerObject(*Buffer);
Registered = true;
}
virtual void deregisterWithDebugger()
{
- JITRegistrar::getGDBRegistrar().deregisterObject(DyldObj->getBuffer());
+ JITRegistrar::getGDBRegistrar().deregisterObject(*Buffer);
}
};
+// The MemoryBuffer passed into this constructor is just a wrapper around the
+// actual memory. Ultimately, the Binary parent class will take ownership of
+// this MemoryBuffer object but not the underlying memory.
template<support::endianness target_endianness, bool is64Bits>
-DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Object,
+DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Wrapper,
error_code &ec)
- : ELFObjectFile<target_endianness, is64Bits>(Object, ec),
- InputData(Object) {
+ : ELFObjectFile<target_endianness, is64Bits>(Wrapper, ec) {
this->isDyldELFObject = true;
}
@@ -148,46 +147,39 @@ void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress(
namespace llvm {
-ObjectImage *RuntimeDyldELF::createObjectImage(
- const MemoryBuffer *ConstInputBuffer) {
- MemoryBuffer *InputBuffer = const_cast<MemoryBuffer*>(ConstInputBuffer);
- std::pair<unsigned char, unsigned char> Ident = getElfArchType(InputBuffer);
+ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) {
+ if (Buffer->getBufferSize() < ELF::EI_NIDENT)
+ llvm_unreachable("Unexpected ELF object size");
+ std::pair<unsigned char, unsigned char> Ident = std::make_pair(
+ (uint8_t)Buffer->getBufferStart()[ELF::EI_CLASS],
+ (uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]);
error_code ec;
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
DyldELFObject<support::little, false> *Obj =
- new DyldELFObject<support::little, false>(InputBuffer, ec);
- return new ELFObjectImage<support::little, false>(Obj);
+ new DyldELFObject<support::little, false>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::little, false>(Buffer, Obj);
}
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) {
DyldELFObject<support::big, false> *Obj =
- new DyldELFObject<support::big, false>(InputBuffer, ec);
- return new ELFObjectImage<support::big, false>(Obj);
+ new DyldELFObject<support::big, false>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::big, false>(Buffer, Obj);
}
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) {
DyldELFObject<support::big, true> *Obj =
- new DyldELFObject<support::big, true>(InputBuffer, ec);
- return new ELFObjectImage<support::big, true>(Obj);
+ new DyldELFObject<support::big, true>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::big, true>(Buffer, Obj);
}
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
DyldELFObject<support::little, true> *Obj =
- new DyldELFObject<support::little, true>(InputBuffer, ec);
- return new ELFObjectImage<support::little, true>(Obj);
+ new DyldELFObject<support::little, true>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::little, true>(Buffer, Obj);
}
else
llvm_unreachable("Unexpected ELF format");
}
-void RuntimeDyldELF::handleObjectLoaded(ObjectImage *Obj)
-{
- Obj->registerWithDebugger();
- // Save the loaded object. It will deregister itself when deleted
- LoadedObject = Obj;
-}
-
RuntimeDyldELF::~RuntimeDyldELF() {
- if (LoadedObject)
- delete LoadedObject;
}
void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
@@ -522,8 +514,9 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
}
}
-bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
- StringRef Magic = InputBuffer->getBuffer().slice(0, ELF::EI_NIDENT);
- return (memcmp(Magic.data(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
+bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const {
+ if (Buffer->getBufferSize() < strlen(ELF::ElfMagic))
+ return false;
+ return (memcmp(Buffer->getBufferStart(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
}
} // namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
index eade49e..3011a06 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
@@ -22,8 +22,6 @@ using namespace llvm;
namespace llvm {
class RuntimeDyldELF : public RuntimeDyldImpl {
protected:
- ObjectImage *LoadedObject;
-
void resolveX86_64Relocation(uint8_t *LocalAddress,
uint64_t FinalAddress,
uint64_t Value,
@@ -60,16 +58,15 @@ protected:
const SymbolTableMap &Symbols,
StubMap &Stubs);
- virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer);
- virtual void handleObjectLoaded(ObjectImage *Obj);
+ virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
public:
RuntimeDyldELF(RTDyldMemoryManager *mm)
- : RuntimeDyldImpl(mm), LoadedObject(0) {}
+ : RuntimeDyldImpl(mm) {}
virtual ~RuntimeDyldELF();
- bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
+ bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
};
} // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index d56cab2..a973340 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -14,8 +14,8 @@
#ifndef LLVM_RUNTIME_DYLD_IMPL_H
#define LLVM_RUNTIME_DYLD_IMPL_H
-#include "ObjectImage.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -33,7 +33,7 @@ using namespace llvm::object;
namespace llvm {
-class MemoryBuffer;
+class ObjectBuffer;
class Twine;
@@ -251,19 +251,13 @@ protected:
/// \brief Resolve relocations to external symbols.
void resolveExternalSymbols();
- virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer);
- virtual void handleObjectLoaded(ObjectImage *Obj)
- {
- // Subclasses may choose to retain this image if they have a use for it
- delete Obj;
- }
-
+ virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
public:
RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
virtual ~RuntimeDyldImpl();
- bool loadObject(const MemoryBuffer *InputBuffer);
+ ObjectImage *loadObject(ObjectBuffer *InputBuffer);
void *getSymbolAddress(StringRef Name) {
// FIXME: Just look up as a function for now. Overly simple of course.
@@ -298,8 +292,7 @@ public:
// Get the error message.
StringRef getErrorString() { return ErrorStr; }
- virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
-
+ virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0;
};
} // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 465e85d..56540c2 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -295,8 +295,10 @@ void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
bool RuntimeDyldMachO::isCompatibleFormat(
- const MemoryBuffer *InputBuffer) const {
- StringRef Magic = InputBuffer->getBuffer().slice(0, 4);
+ const ObjectBuffer *InputBuffer) const {
+ if (InputBuffer->getBufferSize() < 4)
+ return false;
+ StringRef Magic(InputBuffer->getBufferStart(), 4);
if (Magic == "\xFE\xED\xFA\xCE") return true;
if (Magic == "\xCE\xFA\xED\xFE") return true;
if (Magic == "\xFE\xED\xFA\xCF") return true;
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
index 707664c..ef56f55 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
@@ -63,7 +63,7 @@ public:
RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
- bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
+ bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
};
} // end namespace llvm
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index 95de8d8..7b5bd03 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -14,6 +14,8 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/Object/MachOObject.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
@@ -120,12 +122,14 @@ static int executeInput() {
for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
// Load the input memory buffer.
OwningPtr<MemoryBuffer> InputBuffer;
+ OwningPtr<ObjectImage> LoadedObject;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
InputBuffer))
return Error("unable to read input: '" + ec.message() + "'");
- // Load the object file into it.
- if (Dyld.loadObject(InputBuffer.take())) {
+ // Load the object file
+ LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
+ if (!LoadedObject) {
return Error(Dyld.getErrorString());
}
}