Reverting r222828 and r222810-r222812 as they broke the build on Windows.
authorAaron Ballman <aaron@aaronballman.com>
Wed, 26 Nov 2014 15:27:39 +0000 (15:27 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Wed, 26 Nov 2014 15:27:39 +0000 (15:27 +0000)
http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/11753

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222833 91177308-0d34-0410-b5e6-96231b3b80d8

32 files changed:
include/llvm/ExecutionEngine/JITEventListener.h
include/llvm/ExecutionEngine/ObjectBuffer.h [new file with mode: 0644]
include/llvm/ExecutionEngine/ObjectImage.h [new file with mode: 0644]
include/llvm/ExecutionEngine/RTDyldMemoryManager.h
include/llvm/ExecutionEngine/RuntimeDyld.h
lib/ExecutionEngine/CMakeLists.txt
lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
lib/ExecutionEngine/JITEventListener.cpp [new file with mode: 0644]
lib/ExecutionEngine/MCJIT/MCJIT.cpp
lib/ExecutionEngine/MCJIT/MCJIT.h
lib/ExecutionEngine/MCJIT/ObjectBuffer.h [deleted file]
lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp [new file with mode: 0644]
lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp [deleted file]
lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h [new file with mode: 0644]
lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h [new file with mode: 0644]
lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
tools/lli/RemoteMemoryManager.cpp
tools/lli/RemoteMemoryManager.h
tools/llvm-jitlistener/llvm-jitlistener.cpp
tools/llvm-rtdyld/llvm-rtdyld.cpp

index c3edec8..cef3aa2 100644 (file)
@@ -15,7 +15,6 @@
 #ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
 #define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
 
-#include "RuntimeDyld.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/DebugLoc.h"
 #include "llvm/Support/DataTypes.h"
@@ -26,10 +25,7 @@ class Function;
 class MachineFunction;
 class OProfileWrapper;
 class IntelJITEventsWrapper;
-
-namespace object {
-  class ObjectFile;
-}
+class ObjectImage;
 
 /// JITEvent_EmittedFunctionDetails - Helper struct for containing information
 /// about a generated machine code function.
@@ -61,7 +57,7 @@ public:
 
 public:
   JITEventListener() {}
-  virtual ~JITEventListener() {}
+  virtual ~JITEventListener();
 
   /// NotifyObjectEmitted - Called after an object has been successfully
   /// emitted to memory.  NotifyFunctionEmitted will not be called for
@@ -71,15 +67,11 @@ public:
   /// The ObjectImage contains the generated object image
   /// with section headers updated to reflect the address at which sections
   /// were loaded and with relocations performed in-place on debug sections.
-  virtual void NotifyObjectEmitted(const object::ObjectFile &Obj,
-                                   const RuntimeDyld::LoadedObjectInfo &L) {}
+  virtual void NotifyObjectEmitted(const ObjectImage &Obj) {}
 
   /// NotifyFreeingObject - Called just before the memory associated with
   /// a previously emitted object is released.
-  virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {}
-
-  // Get a pointe to the GDB debugger registration listener.
-  static JITEventListener *createGDBRegistrationListener();
+  virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
 
 #if LLVM_USE_INTEL_JITEVENTS
   // Construct an IntelJITEventListener
@@ -113,8 +105,7 @@ public:
     return nullptr;
   }
 #endif // USE_OPROFILE
-private:
-  virtual void anchor();
+
 };
 
 } // end namespace llvm.
diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
new file mode 100644 (file)
index 0000000..ee4820a
--- /dev/null
@@ -0,0 +1,76 @@
+//===---- 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/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+/// 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.
+class ObjectBuffer {
+  virtual void anchor();
+public:
+  ObjectBuffer() {}
+  ObjectBuffer(std::unique_ptr<MemoryBuffer> Buf) : Buffer(std::move(Buf)) {}
+  virtual ~ObjectBuffer() {}
+
+  MemoryBufferRef getMemBuffer() const { return Buffer->getMemBufferRef(); }
+
+  const char *getBufferStart() const { return Buffer->getBufferStart(); }
+  size_t getBufferSize() const { return Buffer->getBufferSize(); }
+  StringRef getBuffer() const { return Buffer->getBuffer(); }
+  StringRef getBufferIdentifier() const {
+    return Buffer->getBufferIdentifier();
+  }
+
+protected:
+  // The memory contained in an ObjectBuffer
+  std::unique_ptr<MemoryBuffer> Buffer;
+};
+
+/// 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 {
+  void anchor() override;
+public:
+  ObjectBufferStream() : OS(SV) {}
+  virtual ~ObjectBufferStream() {}
+
+  raw_ostream &getOStream() { return OS; }
+  void flush()
+  {
+    OS.flush();
+
+    // Make the data accessible via the ObjectBuffer::Buffer
+    Buffer =
+        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 (file)
index 0000000..dc142bd
--- /dev/null
@@ -0,0 +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_EXECUTIONENGINE_OBJECTIMAGE_H
+#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/Object/ObjectFile.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;
+  virtual void anchor();
+
+protected:
+  std::unique_ptr<ObjectBuffer> Buffer;
+
+public:
+  ObjectImage(std::unique_ptr<ObjectBuffer> Input) : Buffer(std::move(Input)) {}
+  virtual ~ObjectImage() {}
+
+  virtual object::symbol_iterator begin_symbols() const = 0;
+  virtual object::symbol_iterator end_symbols() const = 0;
+  iterator_range<object::symbol_iterator> symbols() const {
+    return iterator_range<object::symbol_iterator>(begin_symbols(),
+                                                   end_symbols());
+  }
+
+  virtual object::section_iterator begin_sections() const = 0;
+  virtual object::section_iterator end_sections() const  = 0;
+  iterator_range<object::section_iterator> sections() const {
+    return iterator_range<object::section_iterator>(begin_sections(),
+                                                    end_sections());
+  }
+
+  virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+  // Return the name associated with this ObjectImage.
+  // This is usually the name of the file or MemoryBuffer that the the
+  // ObjectBuffer was constructed from.
+  StringRef getImageName() const { return Buffer->getBufferIdentifier(); }
+
+  // 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;
+
+  virtual object::ObjectFile* getObjectFile() 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_EXECUTIONENGINE_OBJECTIMAGE_H
index ef81cd3..b941efc 100644 (file)
 namespace llvm {
 
 class ExecutionEngine;
-
-  namespace object {
-    class ObjectFile;
-  }
+class ObjectImage;
 
 // RuntimeDyld clients often want to handle the memory management of
 // what gets placed where. For JIT clients, this is the subset of
@@ -112,7 +109,7 @@ public:
   /// address space can use this call to remap the section addresses for the
   /// newly loaded object.
   virtual void notifyObjectLoaded(ExecutionEngine *EE,
-                                  const object::ObjectFile &) {}
+                                  const ObjectImage *) {}
 
   /// This method is called when object loading is complete and section page
   /// permissions can be applied.  It is up to the memory manager implementation
index 799fc34..3605b9e 100644 (file)
 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
 #include "llvm/Support/Memory.h"
-#include <memory>
 
 namespace llvm {
 
 namespace object {
   class ObjectFile;
-  template <typename T> class OwningBinary;
 }
 
 class RuntimeDyldImpl;
 class RuntimeDyldCheckerImpl;
+class ObjectImage;
 
 class RuntimeDyld {
   friend class RuntimeDyldCheckerImpl;
@@ -46,35 +46,22 @@ protected:
   // Any relocations already associated with the symbol will be re-resolved.
   void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
 public:
-
-  /// \brief Information about the loaded object.
-  class LoadedObjectInfo {
-    friend class RuntimeDyldImpl;
-  public:
-    LoadedObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
-                     unsigned EndIdx)
-      : RTDyld(RTDyld), BeginIdx(BeginIdx), EndIdx(EndIdx) { }
-
-    virtual ~LoadedObjectInfo() {}
-
-    virtual object::OwningBinary<object::ObjectFile>
-    getObjectForDebug(const object::ObjectFile &Obj) const = 0;
-
-    uint64_t getSectionLoadAddress(StringRef Name) const;
-
-  protected:
-    virtual void anchor();
-
-    RuntimeDyldImpl &RTDyld;
-    unsigned BeginIdx, EndIdx;
-  };
-
   RuntimeDyld(RTDyldMemoryManager *);
   ~RuntimeDyld();
 
-  /// Add the referenced object file to the list of objects to be loaded and
-  /// relocated.
-  std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O);
+  /// 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.
+  std::unique_ptr<ObjectImage>
+  loadObject(std::unique_ptr<ObjectBuffer> InputBuffer);
+
+  /// Prepare the referenced object file for execution.
+  /// Ownership of the input object is transferred to the ObjectImage
+  /// instance returned from this function if successful. In the case of load
+  /// failure, the input object will be deleted.
+  std::unique_ptr<ObjectImage>
+  loadObject(std::unique_ptr<object::ObjectFile> InputObject);
 
   /// 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
index 208495c..fae5bb9 100644 (file)
@@ -3,6 +3,7 @@
 add_llvm_library(LLVMExecutionEngine
   ExecutionEngine.cpp
   ExecutionEngineBindings.cpp
+  JITEventListener.cpp
   RTDyldMemoryManager.cpp
   TargetSelect.cpp
   )
index 4d4cb2a..5a6d656 100644 (file)
@@ -16,7 +16,8 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/ObjectCache.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -42,15 +43,17 @@ using namespace llvm;
 STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");
 STATISTIC(NumGlobals  , "Number of global vars initialized");
 
+// Pin the vtable to this file.
+void ObjectCache::anchor() {}
+void ObjectBuffer::anchor() {}
+void ObjectBufferStream::anchor() {}
+
 ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
     std::unique_ptr<Module> M, std::string *ErrorStr,
     RTDyldMemoryManager *MCJMM, std::unique_ptr<TargetMachine> TM) = nullptr;
 ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
                                                 std::string *ErrorStr) =nullptr;
 
-// Anchor for the JITEventListener class.
-void JITEventListener::anchor() {}
-
 ExecutionEngine::ExecutionEngine(std::unique_ptr<Module> M)
   : EEState(*this),
     LazyFunctionCreator(nullptr) {
index c35e524..b23ca88 100644 (file)
@@ -21,6 +21,7 @@
 #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"
@@ -31,7 +32,6 @@
 
 using namespace llvm;
 using namespace llvm::jitprofiling;
-using namespace llvm::object;
 
 #define DEBUG_TYPE "amplifier-jit-event-listener"
 
@@ -48,7 +48,6 @@ class IntelJITEventListener : public JITEventListener {
   typedef DenseMap<const void *, MethodAddressVector>  ObjectMap;
 
   ObjectMap  LoadedObjectMap;
-  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
 
 public:
   IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
@@ -58,10 +57,9 @@ public:
   ~IntelJITEventListener() {
   }
 
-  void NotifyObjectEmitted(const ObjectFile &Obj,
-                           const RuntimeDyld::LoadedObjectInfo &L) override;
+  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
 
-  void NotifyFreeingObject(const ObjectFile &Obj) override;
+  virtual void NotifyFreeingObject(const ObjectImage &Obj);
 };
 
 static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress,
@@ -97,29 +95,23 @@ static iJIT_Method_Load FunctionDescToIntelJITFormat(
   return Result;
 }
 
-void IntelJITEventListener::NotifyObjectEmitted(
-                                       const ObjectFile &Obj,
-                                       const RuntimeDyld::LoadedObjectInfo &L) {
-
-  OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
-  const ObjectFile &DebugObj = *DebugObjOwner.getBinary();
-
+void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
   // Get the address of the object image for use as a unique identifier
-  const void* ObjData = DebugObj.getData().data();
-  DIContext* Context = DIContext::getDWARFContext(DebugObj);
+  const void* ObjData = Obj.getData().data();
+  DIContext* Context = DIContext::getDWARFContext(*Obj.getObjectFile());
   MethodAddressVector Functions;
 
   // Use symbol info to iterate functions in the object.
-  for (symbol_iterator I = DebugObj.symbol_begin(),
-                       E = DebugObj.symbol_end();
+  for (object::symbol_iterator I = Obj.begin_symbols(),
+                               E = Obj.end_symbols();
                         I != E;
                         ++I) {
     std::vector<LineNumberInfo> LineInfo;
     std::string SourceFileName;
 
-    SymbolRef::Type SymType;
+    object::SymbolRef::Type SymType;
     if (I->getType(SymType)) continue;
-    if (SymType == SymbolRef::ST_Function) {
+    if (SymType == object::SymbolRef::ST_Function) {
       StringRef  Name;
       uint64_t   Addr;
       uint64_t   Size;
@@ -170,18 +162,11 @@ void IntelJITEventListener::NotifyObjectEmitted(
   // 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 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;
-
+void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
   // Get the address of the object image for use as a unique identifier
-  const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary();
-  const void* ObjData = DebugObj.getData().data();
+  const void* ObjData = Obj.getData().data();
 
   // Get the object's function list from LoadedObjectMap
   ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
@@ -205,7 +190,6 @@ void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
 
   // Erase the object from LoadedObjectMap
   LoadedObjectMap.erase(OI);
-  DebugObjects.erase(Obj.getData().data());
 }
 
 }  // anonymous namespace.
diff --git a/lib/ExecutionEngine/JITEventListener.cpp b/lib/ExecutionEngine/JITEventListener.cpp
new file mode 100644 (file)
index 0000000..2a6a007
--- /dev/null
@@ -0,0 +1,15 @@
+//===-- JITEventListener.cpp ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/JITEventListener.h"
+
+using namespace llvm;
+
+// Out-of-line definition of the virtual destructor as this is the key function.
+JITEventListener::~JITEventListener() {}
index 58cf4e5..da5f037 100644 (file)
@@ -11,6 +11,8 @@
 #include "llvm/ExecutionEngine/GenericValue.h"
 #include "llvm/ExecutionEngine/JITEventListener.h"
 #include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -19,7 +21,6 @@
 #include "llvm/IR/Module.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/Object/Archive.h"
-#include "llvm/Object/ObjectFile.h"
 #include "llvm/PassManager.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -30,8 +31,6 @@
 
 using namespace llvm;
 
-void ObjectCache::anchor() {}
-
 namespace {
 
 static struct RegisterJIT {
@@ -75,7 +74,6 @@ MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
 
   OwnedModules.addModule(std::move(First));
   setDataLayout(TM->getSubtargetImpl()->getDataLayout());
-  RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
 }
 
 MCJIT::~MCJIT() {
@@ -101,13 +99,13 @@ bool MCJIT::removeModule(Module *M) {
 }
 
 void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
-  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
-  if (Dyld.hasError())
+  std::unique_ptr<ObjectImage> LoadedObject = Dyld.loadObject(std::move(Obj));
+  if (!LoadedObject || Dyld.hasError())
     report_fatal_error(Dyld.getErrorString());
 
-  NotifyObjectEmitted(*Obj, *L);
+  NotifyObjectEmitted(*LoadedObject);
 
-  LoadedObjects.push_back(std::move(Obj));
+  LoadedObjects.push_back(std::move(LoadedObject));
 }
 
 void MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
@@ -127,7 +125,7 @@ void MCJIT::setObjectCache(ObjectCache* NewCache) {
   ObjCache = NewCache;
 }
 
-std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
+std::unique_ptr<ObjectBufferStream> MCJIT::emitObject(Module *M) {
   MutexGuard locked(lock);
 
   // This must be a module which has already been added but not loaded to this
@@ -140,32 +138,30 @@ std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
   PM.add(new DataLayoutPass());
 
   // The RuntimeDyld will take ownership of this shortly
-  SmallVector<char, 4096> ObjBufferSV;
-  raw_svector_ostream ObjStream(ObjBufferSV);
+  std::unique_ptr<ObjectBufferStream> CompiledObject(new ObjectBufferStream());
 
   // Turn the machine code intermediate representation into bytes in memory
   // that may be executed.
-  if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules()))
+  if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(),
+                            !getVerifyModules())) {
     report_fatal_error("Target does not support MC emission!");
+  }
 
   // Initialize passes.
   PM.run(*M);
   // Flush the output buffer to get the generated code into memory
-  ObjStream.flush();
-
-  std::unique_ptr<MemoryBuffer> CompiledObjBuffer(
-                                new ObjectMemoryBuffer(std::move(ObjBufferSV)));
+  CompiledObject->flush();
 
   // If we have an object cache, tell it about the new object.
   // Note that we're using the compiled image, not the loaded image (as below).
   if (ObjCache) {
     // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
     // to create a temporary object here and delete it after the call.
-    MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
+    MemoryBufferRef MB = CompiledObject->getMemBuffer();
     ObjCache->notifyObjectCompiled(M, MB);
   }
 
-  return CompiledObjBuffer;
+  return CompiledObject;
 }
 
 void MCJIT::generateCodeForModule(Module *M) {
@@ -180,10 +176,14 @@ void MCJIT::generateCodeForModule(Module *M) {
   if (OwnedModules.hasModuleBeenLoaded(M))
     return;
 
-  std::unique_ptr<MemoryBuffer> ObjectToLoad;
+  std::unique_ptr<ObjectBuffer> ObjectToLoad;
   // Try to load the pre-compiled object from cache if possible
-  if (ObjCache)
-    ObjectToLoad = ObjCache->getObject(M);
+  if (ObjCache) {
+    if (std::unique_ptr<MemoryBuffer> PreCompiledObject =
+            ObjCache->getObject(M))
+      ObjectToLoad =
+          llvm::make_unique<ObjectBuffer>(std::move(PreCompiledObject));
+  }
 
   // If the cache did not contain a suitable object, compile the object
   if (!ObjectToLoad) {
@@ -193,18 +193,17 @@ void MCJIT::generateCodeForModule(Module *M) {
 
   // Load the object into the dynamic linker.
   // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
-  ErrorOr<std::unique_ptr<object::ObjectFile>> LoadedObject =
-    object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
-  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
-    Dyld.loadObject(*LoadedObject.get());
-
-  if (Dyld.hasError())
+  std::unique_ptr<ObjectImage> LoadedObject =
+      Dyld.loadObject(std::move(ObjectToLoad));
+  if (!LoadedObject)
     report_fatal_error(Dyld.getErrorString());
 
-  NotifyObjectEmitted(*LoadedObject.get(), *L);
+  // FIXME: Make this optional, maybe even move it to a JIT event listener
+  LoadedObject->registerWithDebugger();
+
+  NotifyObjectEmitted(*LoadedObject);
 
-  Buffers.push_back(std::move(ObjectToLoad));
-  LoadedObjects.push_back(std::move(*LoadedObject));
+  LoadedObjects.push_back(std::move(LoadedObject));
 
   OwnedModules.markModuleAsLoaded(M);
 }
@@ -550,7 +549,6 @@ void MCJIT::RegisterJITEventListener(JITEventListener *L) {
   MutexGuard locked(lock);
   EventListeners.push_back(L);
 }
-
 void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
   if (!L)
     return;
@@ -561,17 +559,14 @@ void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
     EventListeners.pop_back();
   }
 }
-
-void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj,
-                                const RuntimeDyld::LoadedObjectInfo &L) {
+void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {
   MutexGuard locked(lock);
-  MemMgr.notifyObjectLoaded(this, Obj);
+  MemMgr.notifyObjectLoaded(this, &Obj);
   for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
-    EventListeners[I]->NotifyObjectEmitted(Obj, L);
+    EventListeners[I]->NotifyObjectEmitted(Obj);
   }
 }
-
-void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) {
+void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) {
   MutexGuard locked(lock);
   for (JITEventListener *L : EventListeners)
     L->NotifyFreeingObject(Obj);
index 6f92e51..bc943b9 100644 (file)
 #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
 #define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
 
-#include "ObjectBuffer.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
 #include "llvm/ExecutionEngine/ObjectCache.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/IR/Module.h"
 
@@ -57,7 +57,7 @@ public:
   }
 
   void notifyObjectLoaded(ExecutionEngine *EE,
-                          const object::ObjectFile &Obj) override {
+                          const ObjectImage *Obj) override {
     ClientMM->notifyObjectLoaded(EE, Obj);
   }
 
@@ -222,7 +222,7 @@ class MCJIT : public ExecutionEngine {
   SmallVector<object::OwningBinary<object::Archive>, 2> Archives;
   SmallVector<std::unique_ptr<MemoryBuffer>, 2> Buffers;
 
-  SmallVector<std::unique_ptr<object::ObjectFile>, 2> LoadedObjects;
+  SmallVector<std::unique_ptr<ObjectImage>, 2> LoadedObjects;
 
   // An optional ObjectCache to be notified of compiled objects and used to
   // perform lookup of pre-compiled code to avoid re-compilation.
@@ -341,11 +341,10 @@ protected:
   /// 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
   /// the future.
-  std::unique_ptr<MemoryBuffer> emitObject(Module *M);
+  std::unique_ptr<ObjectBufferStream> emitObject(Module *M);
 
-  void NotifyObjectEmitted(const object::ObjectFile& Obj,
-                           const RuntimeDyld::LoadedObjectInfo &L);
-  void NotifyFreeingObject(const object::ObjectFile& Obj);
+  void NotifyObjectEmitted(const ObjectImage& Obj);
+  void NotifyFreeingObject(const ObjectImage& Obj);
 
   uint64_t getExistingSymbolAddress(const std::string &Name);
   Module *findModuleForSymbol(const std::string &Name,
diff --git a/lib/ExecutionEngine/MCJIT/ObjectBuffer.h b/lib/ExecutionEngine/MCJIT/ObjectBuffer.h
deleted file mode 100644 (file)
index 92310f3..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-//===--- ObjectBuffer.h - Utility class to wrap object memory ---*- C++ -*-===//
-//
-//                     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/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-
-class ObjectMemoryBuffer : public MemoryBuffer {
-public:
-  template <unsigned N>
-  ObjectMemoryBuffer(SmallVector<char, N> SV)
-    : SV(SV), BufferName("<in-memory object>") {
-    init(this->SV.begin(), this->SV.end(), false);
-  }
-
-  template <unsigned N>
-  ObjectMemoryBuffer(SmallVector<char, N> SV, StringRef Name)
-    : SV(SV), BufferName(Name) {
-    init(this->SV.begin(), this->SV.end(), false);
-  }
-  const char* getBufferIdentifier() const override { return BufferName.c_str(); }
-
-  BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }
-
-private:
-  SmallVector<char, 4096> SV;
-  std::string BufferName;
-};
-
-} // namespace llvm
-
-#endif
index 92a67b9..5a8ccb6 100644 (file)
@@ -18,8 +18,8 @@
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/Function.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/ExecutionEngine/OProfileWrapper.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 using namespace llvm::jitprofiling;
-using namespace llvm::object;
 
 #define DEBUG_TYPE "oprofile-jit-event-listener"
 
 namespace {
 
 class OProfileJITEventListener : public JITEventListener {
-  std::unique_ptr<OProfileWrapper> Wrapper;
+  OProfileWrapper& Wrapper;
 
   void initialize();
-  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
 
 public:
-  OProfileJITEventListener(std::unique_ptr<OProfileWrapper> LibraryWrapper)
-    : Wrapper(std::move(LibraryWrapper)) {
+  OProfileJITEventListener(OProfileWrapper& LibraryWrapper)
+  : Wrapper(LibraryWrapper) {
     initialize();
   }
 
   ~OProfileJITEventListener();
 
-  void NotifyObjectEmitted(const ObjectFile &Obj,
-                           const RuntimeDyld::LoadedObjectInfo &L) override;
+  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
 
-  void NotifyFreeingObject(const ObjectFile &Obj) override;
+  virtual void NotifyFreeingObject(const ObjectImage &Obj);
 };
 
 void OProfileJITEventListener::initialize() {
-  if (!Wrapper->op_open_agent()) {
+  if (!Wrapper.op_open_agent()) {
     const std::string err_str = sys::StrError();
     DEBUG(dbgs() << "Failed to connect to OProfile agent: " << err_str << "\n");
   } else {
@@ -67,8 +64,8 @@ void OProfileJITEventListener::initialize() {
 }
 
 OProfileJITEventListener::~OProfileJITEventListener() {
-  if (Wrapper->isAgentAvailable()) {
-    if (Wrapper->op_close_agent() == -1) {
+  if (Wrapper.isAgentAvailable()) {
+    if (Wrapper.op_close_agent() == -1) {
       const std::string err_str = sys::StrError();
       DEBUG(dbgs() << "Failed to disconnect from OProfile agent: "
                    << err_str << "\n");
@@ -78,22 +75,17 @@ OProfileJITEventListener::~OProfileJITEventListener() {
   }
 }
 
-void OProfileJITEventListener::NotifyObjectEmitted(
-                                       const ObjectFile &Obj,
-                                       const RuntimeDyld::LoadedObjectInfo &L) {
-  if (!Wrapper->isAgentAvailable()) {
+void OProfileJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
+  if (!Wrapper.isAgentAvailable()) {
     return;
   }
 
-  OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
-  const ObjectFile &DebugObj = *DebugObjOwner.getBinary();
-
   // Use symbol info to iterate functions in the object.
-  for (symbol_iterator I = DebugObj.symbol_begin(), E = DebugObj.symbol_end();
+  for (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
        I != E; ++I) {
-    SymbolRef::Type SymType;
+    object::SymbolRef::Type SymType;
     if (I->getType(SymType)) continue;
-    if (SymType == SymbolRef::ST_Function) {
+    if (SymType == object::SymbolRef::ST_Function) {
       StringRef  Name;
       uint64_t   Addr;
       uint64_t   Size;
@@ -101,7 +93,7 @@ void OProfileJITEventListener::NotifyObjectEmitted(
       if (I->getAddress(Addr)) continue;
       if (I->getSize(Size)) continue;
 
-      if (Wrapper->op_write_native_code(Name.data(), Addr, (void*)Addr, Size)
+      if (Wrapper.op_write_native_code(Name.data(), Addr, (void*)Addr, Size)
                         == -1) {
         DEBUG(dbgs() << "Failed to tell OProfile about native function "
           << Name << " at ["
@@ -111,48 +103,45 @@ void OProfileJITEventListener::NotifyObjectEmitted(
       // TODO: support line number info (similar to IntelJITEventListener.cpp)
     }
   }
-
-  DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
 }
 
-void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
-  if (Wrapper->isAgentAvailable()) {
-
-    // If there was no agent registered when the original object was loaded then
-    // we won't have created a debug object for it, so bail out.
-    if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end())
-      return;
-
-    const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary();
-
-    // Use symbol info to iterate functions in the object.
-    for (symbol_iterator I = DebugObj.symbol_begin(),
-                         E = DebugObj.symbol_end();
-         I != E; ++I) {
-      SymbolRef::Type SymType;
-      if (I->getType(SymType)) continue;
-      if (SymType == SymbolRef::ST_Function) {
-        uint64_t   Addr;
-        if (I->getAddress(Addr)) continue;
-
-        if (Wrapper->op_unload_native_code(Addr) == -1) {
-          DEBUG(dbgs()
-                << "Failed to tell OProfile about unload of native function at "
-                << (void*)Addr << "\n");
-          continue;
-        }
+void OProfileJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
+  if (!Wrapper.isAgentAvailable()) {
+    return;
+  }
+
+  // Use symbol info to iterate functions in the object.
+  for (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
+       I != E; ++I) {
+    object::SymbolRef::Type SymType;
+    if (I->getType(SymType)) continue;
+    if (SymType == object::SymbolRef::ST_Function) {
+      uint64_t   Addr;
+      if (I->getAddress(Addr)) continue;
+
+      if (Wrapper.op_unload_native_code(Addr) == -1) {
+        DEBUG(dbgs()
+          << "Failed to tell OProfile about unload of native function at "
+          << (void*)Addr << "\n");
+        continue;
       }
     }
   }
-
-  DebugObjects.erase(Obj.getData().data());
 }
 
 }  // anonymous namespace.
 
 namespace llvm {
 JITEventListener *JITEventListener::createOProfileJITEventListener() {
-  return new OProfileJITEventListener(llvm::make_unique<OProfileWrapper>());
+  static std::unique_ptr<OProfileWrapper> JITProfilingWrapper(
+      new OProfileWrapper);
+  return new OProfileJITEventListener(*JITProfilingWrapper);
+}
+
+// for testing
+JITEventListener *JITEventListener::createOProfileJITEventListener(
+                                      OProfileWrapper* TestImpl) {
+  return new OProfileJITEventListener(*TestImpl);
 }
 
 } // namespace llvm
index 583d7a0..eb1a60b 100644 (file)
@@ -1,5 +1,5 @@
 add_llvm_library(LLVMRuntimeDyld
-  GDBRegistrationListener.cpp
+  GDBRegistrar.cpp
   RuntimeDyld.cpp
   RuntimeDyldChecker.cpp
   RuntimeDyldELF.cpp
diff --git a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
new file mode 100644 (file)
index 0000000..dfa3a20
--- /dev/null
@@ -0,0 +1,213 @@
+//===-- GDBRegistrar.cpp - Registers objects with GDB ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITRegistrar.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
+#include "llvm/Support/ManagedStatic.h"
+
+using namespace llvm;
+
+// This must be kept in sync with gdb/gdb/jit.h .
+extern "C" {
+
+  typedef enum {
+    JIT_NOACTION = 0,
+    JIT_REGISTER_FN,
+    JIT_UNREGISTER_FN
+  } jit_actions_t;
+
+  struct jit_code_entry {
+    struct jit_code_entry *next_entry;
+    struct jit_code_entry *prev_entry;
+    const char *symfile_addr;
+    uint64_t symfile_size;
+  };
+
+  struct jit_descriptor {
+    uint32_t version;
+    // This should be jit_actions_t, but we want to be specific about the
+    // bit-width.
+    uint32_t action_flag;
+    struct jit_code_entry *relevant_entry;
+    struct jit_code_entry *first_entry;
+  };
+
+  // We put information about the JITed function in this global, which the
+  // debugger reads.  Make sure to specify the version statically, because the
+  // debugger checks the version before we can set it during runtime.
+  struct jit_descriptor __jit_debug_descriptor = { 1, 0, nullptr, nullptr };
+
+  // Debuggers puts a breakpoint in this function.
+  LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() {
+    // The noinline and the asm prevent calls to this function from being
+    // optimized out.
+#if !defined(_MSC_VER)
+    asm volatile("":::"memory");
+#endif
+  }
+
+}
+
+namespace {
+
+// Buffer for an in-memory object file in executable memory
+typedef llvm::DenseMap< const char*,
+                        std::pair<std::size_t, jit_code_entry*> >
+  RegisteredObjectBufferMap;
+
+/// Global access point for the JIT debugging interface designed for use with a
+/// singleton toolbox. Handles thread-safe registration and deregistration of
+/// object files that are in executable memory managed by the client of this
+/// class.
+class GDBJITRegistrar : public JITRegistrar {
+  /// A map of in-memory object files that have been registered with the
+  /// JIT interface.
+  RegisteredObjectBufferMap ObjectBufferMap;
+
+public:
+  /// Instantiates the JIT service.
+  GDBJITRegistrar() : ObjectBufferMap() {}
+
+  /// Unregisters each object that was previously registered and releases all
+  /// internal resources.
+  virtual ~GDBJITRegistrar();
+
+  /// 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 ObjectBuffer &Object) override;
+
+  /// Removes the internal registration of @p Object, and
+  /// frees associated resources.
+  /// Returns true if @p Object was found in ObjectBufferMap.
+  bool deregisterObject(const ObjectBuffer &Object) override;
+
+private:
+  /// Deregister the debug info for the given object file from the debugger
+  /// and delete any temporary copies.  This private method does not remove
+  /// the function from Map so that it can be called while iterating over Map.
+  void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I);
+};
+
+/// Lock used to serialize all jit registration events, since they
+/// modify global variables.
+ManagedStatic<sys::Mutex> JITDebugLock;
+
+/// Do the registration.
+void NotifyDebugger(jit_code_entry* JITCodeEntry) {
+  __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
+
+  // Insert this entry at the head of the list.
+  JITCodeEntry->prev_entry = nullptr;
+  jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry;
+  JITCodeEntry->next_entry = NextEntry;
+  if (NextEntry) {
+    NextEntry->prev_entry = JITCodeEntry;
+  }
+  __jit_debug_descriptor.first_entry = JITCodeEntry;
+  __jit_debug_descriptor.relevant_entry = JITCodeEntry;
+  __jit_debug_register_code();
+}
+
+GDBJITRegistrar::~GDBJITRegistrar() {
+  // Free all registered object files.
+  llvm::MutexGuard locked(*JITDebugLock);
+  for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end();
+       I != E; ++I) {
+    // Call the private method that doesn't update the map so our iterator
+    // doesn't break.
+    deregisterObjectInternal(I);
+  }
+  ObjectBufferMap.clear();
+}
+
+void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) {
+
+  const char *Buffer = Object.getBufferStart();
+  size_t      Size = Object.getBufferSize();
+
+  assert(Buffer && "Attempt to register a null object with a debugger.");
+  llvm::MutexGuard locked(*JITDebugLock);
+  assert(ObjectBufferMap.find(Buffer) == ObjectBufferMap.end() &&
+         "Second attempt to perform debug registration.");
+  jit_code_entry* JITCodeEntry = new jit_code_entry();
+
+  if (!JITCodeEntry) {
+    llvm::report_fatal_error(
+      "Allocation failed when registering a JIT entry!\n");
+  } else {
+    JITCodeEntry->symfile_addr = Buffer;
+    JITCodeEntry->symfile_size = Size;
+
+    ObjectBufferMap[Buffer] = std::make_pair(Size, JITCodeEntry);
+    NotifyDebugger(JITCodeEntry);
+  }
+}
+
+bool GDBJITRegistrar::deregisterObject(const ObjectBuffer& Object) {
+  const char *Buffer = Object.getBufferStart();
+  llvm::MutexGuard locked(*JITDebugLock);
+  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer);
+
+  if (I != ObjectBufferMap.end()) {
+    deregisterObjectInternal(I);
+    ObjectBufferMap.erase(I);
+    return true;
+  }
+  return false;
+}
+
+void GDBJITRegistrar::deregisterObjectInternal(
+    RegisteredObjectBufferMap::iterator I) {
+
+  jit_code_entry*& JITCodeEntry = I->second.second;
+
+  // Do the unregistration.
+  {
+    __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
+
+    // Remove the jit_code_entry from the linked list.
+    jit_code_entry* PrevEntry = JITCodeEntry->prev_entry;
+    jit_code_entry* NextEntry = JITCodeEntry->next_entry;
+
+    if (NextEntry) {
+      NextEntry->prev_entry = PrevEntry;
+    }
+    if (PrevEntry) {
+      PrevEntry->next_entry = NextEntry;
+    }
+    else {
+      assert(__jit_debug_descriptor.first_entry == JITCodeEntry);
+      __jit_debug_descriptor.first_entry = NextEntry;
+    }
+
+    // Tell the debugger which entry we removed, and unregister the code.
+    __jit_debug_descriptor.relevant_entry = JITCodeEntry;
+    __jit_debug_register_code();
+  }
+
+  delete JITCodeEntry;
+  JITCodeEntry = nullptr;
+}
+
+llvm::ManagedStatic<GDBJITRegistrar> TheRegistrar;
+
+} // end namespace
+
+namespace llvm {
+
+JITRegistrar& JITRegistrar::getGDBRegistrar() {
+  return *TheRegistrar;
+}
+
+} // namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp
deleted file mode 100644 (file)
index 13d5672..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-//===----- GDBRegistrationListener.cpp - Registers objects with GDB -------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ExecutionEngine/JITEventListener.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mutex.h"
-#include "llvm/Support/MutexGuard.h"
-#include "llvm/Support/ManagedStatic.h"
-
-using namespace llvm;
-using namespace llvm::object;
-
-// This must be kept in sync with gdb/gdb/jit.h .
-extern "C" {
-
-  typedef enum {
-    JIT_NOACTION = 0,
-    JIT_REGISTER_FN,
-    JIT_UNREGISTER_FN
-  } jit_actions_t;
-
-  struct jit_code_entry {
-    struct jit_code_entry *next_entry;
-    struct jit_code_entry *prev_entry;
-    const char *symfile_addr;
-    uint64_t symfile_size;
-  };
-
-  struct jit_descriptor {
-    uint32_t version;
-    // This should be jit_actions_t, but we want to be specific about the
-    // bit-width.
-    uint32_t action_flag;
-    struct jit_code_entry *relevant_entry;
-    struct jit_code_entry *first_entry;
-  };
-
-  // We put information about the JITed function in this global, which the
-  // debugger reads.  Make sure to specify the version statically, because the
-  // debugger checks the version before we can set it during runtime.
-  struct jit_descriptor __jit_debug_descriptor = { 1, 0, nullptr, nullptr };
-
-  // Debuggers puts a breakpoint in this function.
-  LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() {
-    // The noinline and the asm prevent calls to this function from being
-    // optimized out.
-#if !defined(_MSC_VER)
-    asm volatile("":::"memory");
-#endif
-  }
-
-}
-
-namespace {
-
-struct RegisteredObjectInfo {
-  RegisteredObjectInfo() {}
-
-  RegisteredObjectInfo(std::size_t Size, jit_code_entry *Entry,
-                       OwningBinary<ObjectFile> Obj)
-    : Size(Size), Entry(Entry), Obj(std::move(Obj)) {}
-
-  std::size_t Size;
-  jit_code_entry *Entry;
-  OwningBinary<ObjectFile> Obj;
-};
-
-// Buffer for an in-memory object file in executable memory
-typedef llvm::DenseMap< const char*, RegisteredObjectInfo>
-  RegisteredObjectBufferMap;
-
-/// Global access point for the JIT debugging interface designed for use with a
-/// singleton toolbox. Handles thread-safe registration and deregistration of
-/// object files that are in executable memory managed by the client of this
-/// class.
-class GDBJITRegistrationListener : public JITEventListener {
-  /// A map of in-memory object files that have been registered with the
-  /// JIT interface.
-  RegisteredObjectBufferMap ObjectBufferMap;
-
-public:
-  /// Instantiates the JIT service.
-  GDBJITRegistrationListener() : ObjectBufferMap() {}
-
-  /// Unregisters each object that was previously registered and releases all
-  /// internal resources.
-  virtual ~GDBJITRegistrationListener();
-
-  /// 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 NotifyObjectEmitted(const ObjectFile &Object,
-                           const RuntimeDyld::LoadedObjectInfo &L) override;
-
-  /// Removes the internal registration of @p Object, and
-  /// frees associated resources.
-  /// Returns true if @p Object was found in ObjectBufferMap.
-  void NotifyFreeingObject(const ObjectFile &Object) override;
-
-private:
-  /// Deregister the debug info for the given object file from the debugger
-  /// and delete any temporary copies.  This private method does not remove
-  /// the function from Map so that it can be called while iterating over Map.
-  void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I);
-};
-
-/// Lock used to serialize all jit registration events, since they
-/// modify global variables.
-ManagedStatic<sys::Mutex> JITDebugLock;
-
-/// Do the registration.
-void NotifyDebugger(jit_code_entry* JITCodeEntry) {
-  __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
-
-  // Insert this entry at the head of the list.
-  JITCodeEntry->prev_entry = nullptr;
-  jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry;
-  JITCodeEntry->next_entry = NextEntry;
-  if (NextEntry) {
-    NextEntry->prev_entry = JITCodeEntry;
-  }
-  __jit_debug_descriptor.first_entry = JITCodeEntry;
-  __jit_debug_descriptor.relevant_entry = JITCodeEntry;
-  __jit_debug_register_code();
-}
-
-GDBJITRegistrationListener::~GDBJITRegistrationListener() {
-  // Free all registered object files.
-  llvm::MutexGuard locked(*JITDebugLock);
-  for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(),
-                                           E = ObjectBufferMap.end();
-       I != E; ++I) {
-    // Call the private method that doesn't update the map so our iterator
-    // doesn't break.
-    deregisterObjectInternal(I);
-  }
-  ObjectBufferMap.clear();
-}
-
-void GDBJITRegistrationListener::NotifyObjectEmitted(
-                                       const ObjectFile &Object,
-                                       const RuntimeDyld::LoadedObjectInfo &L) {
-
-  OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Object);
-
-  // Bail out if debug objects aren't supported.
-  if (!DebugObj.getBinary())
-    return;
-
-  const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
-  size_t      Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
-
-  const char *Key = Object.getMemoryBufferRef().getBufferStart();
-
-  assert(Key && "Attempt to register a null object with a debugger.");
-  llvm::MutexGuard locked(*JITDebugLock);
-  assert(ObjectBufferMap.find(Key) == ObjectBufferMap.end() &&
-         "Second attempt to perform debug registration.");
-  jit_code_entry* JITCodeEntry = new jit_code_entry();
-
-  if (!JITCodeEntry) {
-    llvm::report_fatal_error(
-      "Allocation failed when registering a JIT entry!\n");
-  } else {
-    JITCodeEntry->symfile_addr = Buffer;
-    JITCodeEntry->symfile_size = Size;
-
-    ObjectBufferMap[Key] = RegisteredObjectInfo(Size, JITCodeEntry,
-                                                std::move(DebugObj));
-    NotifyDebugger(JITCodeEntry);
-  }
-}
-
-void GDBJITRegistrationListener::NotifyFreeingObject(const ObjectFile& Object) {
-  const char *Key = Object.getMemoryBufferRef().getBufferStart();
-  llvm::MutexGuard locked(*JITDebugLock);
-  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Key);
-
-  if (I != ObjectBufferMap.end()) {
-    deregisterObjectInternal(I);
-    ObjectBufferMap.erase(I);
-  }
-}
-
-void GDBJITRegistrationListener::deregisterObjectInternal(
-    RegisteredObjectBufferMap::iterator I) {
-
-  jit_code_entry*& JITCodeEntry = I->second.Entry;
-
-  // Do the unregistration.
-  {
-    __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
-
-    // Remove the jit_code_entry from the linked list.
-    jit_code_entry* PrevEntry = JITCodeEntry->prev_entry;
-    jit_code_entry* NextEntry = JITCodeEntry->next_entry;
-
-    if (NextEntry) {
-      NextEntry->prev_entry = PrevEntry;
-    }
-    if (PrevEntry) {
-      PrevEntry->next_entry = NextEntry;
-    }
-    else {
-      assert(__jit_debug_descriptor.first_entry == JITCodeEntry);
-      __jit_debug_descriptor.first_entry = NextEntry;
-    }
-
-    // Tell the debugger which entry we removed, and unregister the code.
-    __jit_debug_descriptor.relevant_entry = JITCodeEntry;
-    __jit_debug_register_code();
-  }
-
-  delete JITCodeEntry;
-  JITCodeEntry = nullptr;
-}
-
-llvm::ManagedStatic<GDBJITRegistrationListener> GDBRegListener;
-
-} // end namespace
-
-namespace llvm {
-
-JITEventListener* JITEventListener::createGDBRegistrationListener() {
-  return &*GDBRegListener;
-}
-
-} // namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h b/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
new file mode 100644 (file)
index 0000000..636011f
--- /dev/null
@@ -0,0 +1,44 @@
+//===-- JITRegistrar.h - Registers objects with a debugger ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_JITREGISTRAR_H
+#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_JITREGISTRAR_H
+
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+
+namespace llvm {
+
+/// Global access point for the JIT debugging interface.
+class JITRegistrar {
+  virtual void anchor();
+public:
+  /// Instantiates the JIT service.
+  JITRegistrar() {}
+
+  /// Unregisters each object that was previously registered and releases all
+  /// internal resources.
+  virtual ~JITRegistrar() {}
+
+  /// 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 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 ObjectBuffer &Object) = 0;
+
+  /// Returns a reference to a GDB JIT registrar singleton
+  static JITRegistrar& getGDBRegistrar();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
new file mode 100644 (file)
index 0000000..9bbf6a0
--- /dev/null
@@ -0,0 +1,86 @@
+//===-- 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_LIB_EXECUTIONENGINE_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
+#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
+
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/Object/ObjectFile.h"
+
+#include <memory>
+
+namespace llvm {
+
+namespace object {
+  class ObjectFile;
+}
+
+class ObjectImageCommon : public ObjectImage {
+  ObjectImageCommon(); // = delete
+  ObjectImageCommon(const ObjectImageCommon &other); // = delete
+  void anchor() override;
+
+protected:
+  std::unique_ptr<object::ObjectFile> ObjFile;
+
+  // This form of the constructor allows subclasses to use
+  // format-specific subclasses of ObjectFile directly
+  ObjectImageCommon(std::unique_ptr<ObjectBuffer> Input,
+                    std::unique_ptr<object::ObjectFile> Obj)
+      : ObjectImage(std::move(Input)), ObjFile(std::move(Obj)) {}
+
+public:
+  ObjectImageCommon(std::unique_ptr<ObjectBuffer> Input)
+      : ObjectImage(std::move(Input)) {
+    // FIXME: error checking? createObjectFile returns an ErrorOr<ObjectFile*>
+    // and should probably be checked for failure.
+    MemoryBufferRef Buf = Buffer->getMemBuffer();
+    ObjFile = std::move(object::ObjectFile::createObjectFile(Buf).get());
+  }
+  ObjectImageCommon(std::unique_ptr<object::ObjectFile> Input)
+  : ObjectImage(nullptr), ObjFile(std::move(Input))  {}
+  virtual ~ObjectImageCommon() { }
+
+  object::symbol_iterator begin_symbols() const override
+      { return ObjFile->symbol_begin(); }
+  object::symbol_iterator end_symbols() const override
+      { return ObjFile->symbol_end(); }
+
+  object::section_iterator begin_sections() const override
+      { return ObjFile->section_begin(); }
+  object::section_iterator end_sections() const override
+      { return ObjFile->section_end(); }
+
+  /* Triple::ArchType */ unsigned getArch() const override
+      { return ObjFile->getArch(); }
+
+  StringRef getData() const override { return ObjFile->getData(); }
+
+  object::ObjectFile* getObjectFile() const override { return ObjFile.get(); }
+
+  // Subclasses can override these methods to update the image with loaded
+  // addresses for sections and common symbols
+  void updateSectionAddress(const object::SectionRef &Sec,
+                            uint64_t Addr) override {}
+  void updateSymbolAddress(const object::SymbolRef &Sym,
+                           uint64_t Addr) override {}
+
+  // Subclasses can override these methods to provide JIT debugging support
+  void registerWithDebugger() override {}
+  void deregisterWithDebugger() override {}
+};
+
+} // end namespace llvm
+
+#endif
index af9a805..c7c67f6 100644 (file)
@@ -12,6 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "JITRegistrar.h"
+#include "ObjectImageCommon.h"
 #include "RuntimeDyldCheckerImpl.h"
 #include "RuntimeDyldELF.h"
 #include "RuntimeDyldImpl.h"
@@ -28,8 +30,10 @@ using namespace llvm::object;
 // Empty out-of-line virtual destructor as the key function.
 RuntimeDyldImpl::~RuntimeDyldImpl() {}
 
-// Pin LoadedObjectInfo's vtables to this file.
-void RuntimeDyld::LoadedObjectInfo::anchor() {}
+// Pin the JITRegistrar's and ObjectImage*'s vtables to this file.
+void JITRegistrar::anchor() {}
+void ObjectImage::anchor() {}
+void ObjectImageCommon::anchor() {}
 
 namespace llvm {
 
@@ -135,23 +139,22 @@ static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) {
   return object_error::success;
 }
 
-std::pair<unsigned, unsigned>
-RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
+std::unique_ptr<ObjectImage>
+RuntimeDyldImpl::loadObject(std::unique_ptr<ObjectImage> Obj) {
   MutexGuard locked(lock);
 
-  // Grab the first Section ID. We'll use this later to construct the underlying
-  // range for the returned LoadedObjectInfo.
-  unsigned SectionsAddedBeginIdx = Sections.size();
+  if (!Obj)
+    return nullptr;
 
   // Save information about our target
-  Arch = (Triple::ArchType)Obj.getArch();
-  IsTargetLittleEndian = Obj.isLittleEndian();
+  Arch = (Triple::ArchType)Obj->getArch();
+  IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian();
 
   // Compute the memory size required to load all sections to be loaded
   // and pass this information to the memory manager
   if (MemMgr->needsToReserveAllocationSpace()) {
     uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
-    computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW);
+    computeTotalAllocSize(*Obj, CodeSize, DataSizeRO, DataSizeRW);
     MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
   }
 
@@ -167,7 +170,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
 
   // Parse symbols
   DEBUG(dbgs() << "Parse symbols:\n");
-  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
+  for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E;
        ++I) {
     object::SymbolRef::Type SymType;
     StringRef Name;
@@ -193,15 +196,15 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
           SymType == object::SymbolRef::ST_Unknown) {
         uint64_t SectOffset;
         StringRef SectionData;
-        section_iterator SI = Obj.section_end();
+        section_iterator SI = Obj->end_sections();
         Check(getOffset(*I, SectOffset));
         Check(I->getSection(SI));
-        if (SI == Obj.section_end())
+        if (SI == Obj->end_sections())
           continue;
         Check(SI->getContents(SectionData));
         bool IsCode = SI->isText();
         unsigned SectionID =
-            findOrEmitSection(Obj, *SI, IsCode, LocalSections);
+            findOrEmitSection(*Obj, *SI, IsCode, LocalSections);
         LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
         DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset)
                      << " flags: " << Flags << " SID: " << SectionID);
@@ -213,11 +216,11 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
 
   // Allocate common symbols
   if (CommonSize != 0)
-    emitCommonSymbols(Obj, CommonSymbols, CommonSize, GlobalSymbolTable);
+    emitCommonSymbols(*Obj, CommonSymbols, CommonSize, GlobalSymbolTable);
 
   // Parse and process relocations
   DEBUG(dbgs() << "Parse relocations:\n");
-  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
+  for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections();
        SI != SE; ++SI) {
     unsigned SectionID = 0;
     StubMap Stubs;
@@ -231,25 +234,23 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
 
     bool IsCode = RelocatedSection->isText();
     SectionID =
-        findOrEmitSection(Obj, *RelocatedSection, IsCode, LocalSections);
+        findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
     DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
 
     for (; I != E;)
-      I = processRelocationRef(SectionID, I, Obj, LocalSections, LocalSymbols,
+      I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols,
                                Stubs);
 
     // If there is an attached checker, notify it about the stubs for this
     // section so that they can be verified.
     if (Checker)
-      Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
+      Checker->registerStubMap(Obj->getImageName(), SectionID, Stubs);
   }
 
   // Give the subclasses a chance to tie-up any loose ends.
-  finalizeLoad(Obj, LocalSections);
-
-  unsigned SectionsAddedEndIdx = Sections.size();
+  finalizeLoad(*Obj, LocalSections);
 
-  return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
+  return Obj;
 }
 
 // A helper method for computeTotalAllocSize.
@@ -269,7 +270,7 @@ computeAllocationSizeForSections(std::vector<uint64_t> &SectionSizes,
 
 // Compute an upper bound of the memory size that is required to load all
 // sections
-void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
+void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
                                             uint64_t &CodeSize,
                                             uint64_t &DataSizeRO,
                                             uint64_t &DataSizeRW) {
@@ -281,7 +282,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
 
   // Collect sizes of all sections to be loaded;
   // also determine the max alignment of all sections
-  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
+  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
        SI != SE; ++SI) {
     const SectionRef &Section = *SI;
 
@@ -327,7 +328,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
 
   // Compute the size of all common symbols
   uint64_t CommonSize = 0;
-  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
+  for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
        ++I) {
     uint32_t Flags = I->getFlags();
     if (Flags & SymbolRef::SF_Common) {
@@ -352,7 +353,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
 }
 
 // compute stub buffer size for the given section
-unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
+unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
                                                     const SectionRef &Section) {
   unsigned StubSize = getMaxStubSize();
   if (StubSize == 0) {
@@ -362,7 +363,7 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
   // necessary section allocation size in loadObject by walking all the sections
   // once.
   unsigned StubBufSize = 0;
-  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
+  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
        SI != SE; ++SI) {
     section_iterator RelSecI = SI->getRelocatedSection();
     if (!(RelSecI == Section))
@@ -417,7 +418,7 @@ void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst,
   }
 }
 
-void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
+void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
                                         const CommonSymbolMap &CommonSymbols,
                                         uint64_t TotalSize,
                                         SymbolTableMap &SymbolTable) {
@@ -449,13 +450,14 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
       DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
                    << format("%p\n", Addr));
     }
+    Obj.updateSymbolAddress(it->first, (uint64_t)Addr);
     SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset);
     Offset += Size;
     Addr += Size;
   }
 }
 
-unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
+unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
                                       const SectionRef &Section, bool IsCode) {
 
   StringRef data;
@@ -519,6 +521,7 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
                  << " new addr: " << format("%p", Addr)
                  << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
                  << " Allocate: " << Allocate << "\n");
+    Obj.updateSectionAddress(Section, (uint64_t)Addr);
   } else {
     // Even if we didn't load the section, we need to record an entry for it
     // to handle later processing (and by 'handle' I mean don't do anything
@@ -534,12 +537,12 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
   Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
 
   if (Checker)
-    Checker->registerSection(Obj.getFileName(), SectionID);
+    Checker->registerSection(Obj.getImageName(), SectionID);
 
   return SectionID;
 }
 
-unsigned RuntimeDyldImpl::findOrEmitSection(const ObjectFile &Obj,
+unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj,
                                             const SectionRef &Section,
                                             bool IsCode,
                                             ObjSectionToIDMap &LocalSections) {
@@ -736,16 +739,6 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
 
 //===----------------------------------------------------------------------===//
 // RuntimeDyld class implementation
-
-uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress(
-                                                  StringRef SectionName) const {
-  for (unsigned I = BeginIdx; I != EndIdx; ++I)
-    if (RTDyld.Sections[I].Name == SectionName)
-      return RTDyld.Sections[I].LoadAddress;
-
-  return 0;
-}
-
 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
   // FIXME: There's a potential issue lurking here if a single instance of
   // RuntimeDyld is used to load multiple objects.  The current implementation
@@ -779,23 +772,78 @@ createRuntimeDyldMachO(Triple::ArchType Arch, RTDyldMemoryManager *MM,
   return Dyld;
 }
 
-std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
-RuntimeDyld::loadObject(const ObjectFile &Obj) {
-  if (!Dyld) {
-    if (Obj.isELF())
+std::unique_ptr<ObjectImage>
+RuntimeDyld::loadObject(std::unique_ptr<ObjectFile> InputObject) {
+  std::unique_ptr<ObjectImage> InputImage;
+
+  ObjectFile &Obj = *InputObject;
+
+  if (InputObject->isELF()) {
+    InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(std::move(InputObject)));
+    if (!Dyld)
       Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker);
-    else if (Obj.isMachO())
+  } else if (InputObject->isMachO()) {
+    InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject)));
+    if (!Dyld)
       Dyld = createRuntimeDyldMachO(
-               static_cast<Triple::ArchType>(Obj.getArch()), MM,
-               ProcessAllSections, Checker);
-    else
-      report_fatal_error("Incompatible object format!");
+          static_cast<Triple::ArchType>(InputImage->getArch()), MM,
+          ProcessAllSections, Checker);
+  } else
+    report_fatal_error("Incompatible object format!");
+
+  if (!Dyld->isCompatibleFile(&Obj))
+    report_fatal_error("Incompatible object format!");
+
+  return Dyld->loadObject(std::move(InputImage));
+}
+
+std::unique_ptr<ObjectImage>
+RuntimeDyld::loadObject(std::unique_ptr<ObjectBuffer> InputBuffer) {
+  std::unique_ptr<ObjectImage> InputImage;
+  sys::fs::file_magic Type = sys::fs::identify_magic(InputBuffer->getBuffer());
+  auto *InputBufferPtr = InputBuffer.get();
+
+  switch (Type) {
+  case sys::fs::file_magic::elf:
+  case sys::fs::file_magic::elf_relocatable:
+  case sys::fs::file_magic::elf_executable:
+  case sys::fs::file_magic::elf_shared_object:
+  case sys::fs::file_magic::elf_core:
+    InputImage = RuntimeDyldELF::createObjectImage(std::move(InputBuffer));
+    if (!Dyld)
+      Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker);
+    break;
+  case sys::fs::file_magic::macho_object:
+  case sys::fs::file_magic::macho_executable:
+  case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
+  case sys::fs::file_magic::macho_core:
+  case sys::fs::file_magic::macho_preload_executable:
+  case sys::fs::file_magic::macho_dynamically_linked_shared_lib:
+  case sys::fs::file_magic::macho_dynamic_linker:
+  case sys::fs::file_magic::macho_bundle:
+  case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
+  case sys::fs::file_magic::macho_dsym_companion:
+    InputImage = RuntimeDyldMachO::createObjectImage(std::move(InputBuffer));
+    if (!Dyld)
+      Dyld = createRuntimeDyldMachO(
+          static_cast<Triple::ArchType>(InputImage->getArch()), MM,
+          ProcessAllSections, Checker);
+    break;
+  case sys::fs::file_magic::unknown:
+  case sys::fs::file_magic::bitcode:
+  case sys::fs::file_magic::archive:
+  case sys::fs::file_magic::coff_object:
+  case sys::fs::file_magic::coff_import_library:
+  case sys::fs::file_magic::pecoff_executable:
+  case sys::fs::file_magic::macho_universal_binary:
+  case sys::fs::file_magic::windows_resource:
+    report_fatal_error("Incompatible object format!");
   }
 
-  if (!Dyld->isCompatibleFile(Obj))
+  if (!Dyld->isCompatibleFormat(InputBufferPtr))
     report_fatal_error("Incompatible object format!");
 
-  return Dyld->loadObject(Obj);
+  return Dyld->loadObject(std::move(InputImage));
 }
 
 void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
index d213cc9..d95cffe 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "RuntimeDyldELF.h"
+#include "JITRegistrar.h"
+#include "ObjectImageCommon.h"
 #include "llvm/ADT/IntervalMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
-#include "llvm/MC/MCStreamer.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/TargetRegistry.h"
 
 using namespace llvm;
 using namespace llvm::object;
 
 #define DEBUG_TYPE "dyld"
 
+namespace {
+
 static inline std::error_code check(std::error_code Err) {
   if (Err) {
     report_fatal_error(Err.message());
@@ -36,8 +40,6 @@ static inline std::error_code check(std::error_code Err) {
   return Err;
 }
 
-namespace {
-
 template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
 
@@ -50,12 +52,16 @@ template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
 
   typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
 
+  std::unique_ptr<ObjectFile> UnderlyingFile;
+
 public:
+  DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
+                MemoryBufferRef Wrapper, std::error_code &ec);
+
   DyldELFObject(MemoryBufferRef Wrapper, std::error_code &ec);
 
   void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
-
-  void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr);
+  void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr);
 
   // Methods for type inquiry through isa, cast and dyn_cast
   static inline bool classof(const Binary *v) {
@@ -65,10 +71,42 @@ public:
   static inline bool classof(const ELFObjectFile<ELFT> *v) {
     return v->isDyldType();
   }
-
 };
 
+template <class ELFT> class ELFObjectImage : public ObjectImageCommon {
+  bool Registered;
+
+public:
+  ELFObjectImage(std::unique_ptr<ObjectBuffer> Input,
+                 std::unique_ptr<DyldELFObject<ELFT>> Obj)
+      : ObjectImageCommon(std::move(Input), std::move(Obj)), Registered(false) {
+  }
+
+  virtual ~ELFObjectImage() {
+    if (Registered)
+      deregisterWithDebugger();
+  }
+
+  // Subclasses can override these methods to update the image with loaded
+  // addresses for sections and common symbols
+  void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) override {
+    static_cast<DyldELFObject<ELFT>*>(getObjectFile())
+        ->updateSectionAddress(Sec, Addr);
+  }
+
+  void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) override {
+    static_cast<DyldELFObject<ELFT>*>(getObjectFile())
+        ->updateSymbolAddress(Sym, Addr);
+  }
 
+  void registerWithDebugger() override {
+    JITRegistrar::getGDBRegistrar().registerObject(*Buffer);
+    Registered = true;
+  }
+  void deregisterWithDebugger() override {
+    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
@@ -79,6 +117,14 @@ DyldELFObject<ELFT>::DyldELFObject(MemoryBufferRef Wrapper, std::error_code &EC)
   this->isDyldELFObject = true;
 }
 
+template <class ELFT>
+DyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
+                                   MemoryBufferRef Wrapper, std::error_code &EC)
+    : ELFObjectFile<ELFT>(Wrapper, EC),
+      UnderlyingFile(std::move(UnderlyingFile)) {
+  this->isDyldELFObject = true;
+}
+
 template <class ELFT>
 void DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec,
                                                uint64_t Addr) {
@@ -103,89 +149,10 @@ void DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef,
   sym->st_value = static_cast<addr_type>(Addr);
 }
 
-class LoadedELFObjectInfo : public RuntimeDyld::LoadedObjectInfo {
-public:
-  LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
-                      unsigned EndIdx)
-    : RuntimeDyld::LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {}
-
-  OwningBinary<ObjectFile>
-  getObjectForDebug(const ObjectFile &Obj) const override;
-};
-
-template <typename ELFT>
-std::unique_ptr<DyldELFObject<ELFT>>
-createRTDyldELFObject(MemoryBufferRef Buffer,
-                      const LoadedELFObjectInfo &L,
-                      std::error_code &ec) {
-  typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
-  typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
-
-  std::unique_ptr<DyldELFObject<ELFT>> Obj =
-    llvm::make_unique<DyldELFObject<ELFT>>(Buffer, ec);
-
-  // Iterate over all sections in the object.
-  for (const auto &Sec : Obj->sections()) {
-    StringRef SectionName;
-    Sec.getName(SectionName);
-    if (SectionName != "") {
-      DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
-      Elf_Shdr *shdr = const_cast<Elf_Shdr *>(
-          reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
-
-      if (uint64_t SecLoadAddr = L.getSectionLoadAddress(SectionName)) {
-        // This assumes that the address passed in matches the target address
-        // bitness. The template-based type cast handles everything else.
-        shdr->sh_addr = static_cast<addr_type>(SecLoadAddr);
-      }
-    }
-  }
-
-  return Obj;
-}
-
-OwningBinary<ObjectFile> createELFDebugObject(const ObjectFile &Obj,
-                                              const LoadedELFObjectInfo &L) {
-  assert(Obj.isELF() && "Not an ELF object file.");
-
-  std::unique_ptr<MemoryBuffer> Buffer =
-    MemoryBuffer::getMemBufferCopy(Obj.getData(), Obj.getFileName());
-
-  std::error_code ec;
-
-  std::unique_ptr<ObjectFile> DebugObj;
-  if (Obj.getBytesInAddress() == 4 && Obj.isLittleEndian()) {
-    typedef ELFType<support::little, 2, false> ELF32LE;
-    DebugObj = createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), L, ec);
-  } else if (Obj.getBytesInAddress() == 4 && !Obj.isLittleEndian()) {
-    typedef ELFType<support::big, 2, false> ELF32BE;
-    DebugObj = createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), L, ec);
-  } else if (Obj.getBytesInAddress() == 8 && !Obj.isLittleEndian()) {
-    typedef ELFType<support::big, 2, true> ELF64BE;
-    DebugObj = createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), L, ec);
-  } else if (Obj.getBytesInAddress() == 8 && Obj.isLittleEndian()) {
-    typedef ELFType<support::little, 2, true> ELF64LE;
-    DebugObj = createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), L, ec);
-  } else
-    llvm_unreachable("Unexpected ELF format");
-
-  assert(!ec && "Could not construct copy ELF object file");
-
-  return OwningBinary<ObjectFile>(std::move(DebugObj), std::move(Buffer));
-}
-
-OwningBinary<ObjectFile>
-LoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const {
-  return createELFDebugObject(Obj, *this);
-}
-
 } // namespace
 
 namespace llvm {
 
-RuntimeDyldELF::RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
-RuntimeDyldELF::~RuntimeDyldELF() {}
-
 void RuntimeDyldELF::registerEHFrames() {
   if (!MemMgr)
     return;
@@ -213,14 +180,83 @@ void RuntimeDyldELF::deregisterEHFrames() {
   RegisteredEHFrameSections.clear();
 }
 
-std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
-RuntimeDyldELF::loadObject(const object::ObjectFile &O) {
-  unsigned SectionStartIdx, SectionEndIdx;
-  std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O);
-  return llvm::make_unique<LoadedELFObjectInfo>(*this, SectionStartIdx,
-                                                SectionEndIdx);
+ObjectImage *
+RuntimeDyldELF::createObjectImageFromFile(std::unique_ptr<object::ObjectFile> ObjFile) {
+  if (!ObjFile)
+    return nullptr;
+
+  std::error_code ec;
+  MemoryBufferRef Buffer = ObjFile->getMemoryBufferRef();
+
+  if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) {
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::little, 2, false>>>(
+            std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::little, 2, false>>(
+        nullptr, std::move(Obj));
+  } else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) {
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::big, 2, false>>>(
+            std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::big, 2, false>>(nullptr, std::move(Obj));
+  } else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) {
+    auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 2, true>>>(
+        std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::big, 2, true>>(nullptr,
+                                                              std::move(Obj));
+  } else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) {
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::little, 2, true>>>(
+            std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::little, 2, true>>(
+        nullptr, std::move(Obj));
+  } else
+    llvm_unreachable("Unexpected ELF format");
 }
 
+std::unique_ptr<ObjectImage>
+RuntimeDyldELF::createObjectImage(std::unique_ptr<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]);
+  std::error_code ec;
+
+  MemoryBufferRef Buf = Buffer->getMemBuffer();
+
+  if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::little, 4, false>>>(
+            Buf, ec);
+    return llvm::make_unique<
+        ELFObjectImage<ELFType<support::little, 4, false>>>(std::move(Buffer),
+                                                            std::move(Obj));
+  }
+  if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) {
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::big, 4, false>>>(Buf,
+                                                                          ec);
+    return llvm::make_unique<ELFObjectImage<ELFType<support::big, 4, false>>>(
+        std::move(Buffer), std::move(Obj));
+  }
+  if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) {
+    auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 8, true>>>(
+        Buf, ec);
+    return llvm::make_unique<ELFObjectImage<ELFType<support::big, 8, true>>>(
+        std::move(Buffer), std::move(Obj));
+  }
+  assert(Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB &&
+         "Unexpected ELF format");
+  auto Obj =
+      llvm::make_unique<DyldELFObject<ELFType<support::little, 8, true>>>(Buf,
+                                                                          ec);
+  return llvm::make_unique<ELFObjectImage<ELFType<support::little, 8, true>>>(
+      std::move(Buffer), std::move(Obj));
+}
+
+RuntimeDyldELF::~RuntimeDyldELF() {}
+
 void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
                                              uint64_t Offset, uint64_t Value,
                                              uint32_t Type, int64_t Addend,
@@ -579,7 +615,7 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
 }
 
 // Return the .TOC. section and offset.
-void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
+void RuntimeDyldELF::findPPC64TOCSection(ObjectImage &Obj,
                                          ObjSectionToIDMap &LocalSections,
                                          RelocationValueRef &Rel) {
   // Set a default SectionID in case we do not find a TOC section below.
@@ -592,7 +628,7 @@ void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
 
   // The TOC consists of sections .got, .toc, .tocbss, .plt in that
   // order. The TOC starts where the first of these sections starts.
-  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
+  for (section_iterator si = Obj.begin_sections(), se = Obj.end_sections();
        si != se; ++si) {
 
     StringRef SectionName;
@@ -614,15 +650,15 @@ void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
 
 // Returns the sections and offset associated with the ODP entry referenced
 // by Symbol.
-void RuntimeDyldELF::findOPDEntrySection(const ObjectFile &Obj,
+void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
                                          ObjSectionToIDMap &LocalSections,
                                          RelocationValueRef &Rel) {
   // Get the ELF symbol value (st_value) to compare with Relocation offset in
   // .opd entries
-  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
+  for (section_iterator si = Obj.begin_sections(), se = Obj.end_sections();
        si != se; ++si) {
     section_iterator RelSecI = si->getRelocatedSection();
-    if (RelSecI == Obj.section_end())
+    if (RelSecI == Obj.end_sections())
       continue;
 
     StringRef RelSectionName;
@@ -664,7 +700,7 @@ void RuntimeDyldELF::findOPDEntrySection(const ObjectFile &Obj,
       if (Rel.Addend != (int64_t)TargetSymbolOffset)
         continue;
 
-      section_iterator tsi(Obj.section_end());
+      section_iterator tsi(Obj.end_sections());
       check(TargetSymbol->getSection(tsi));
       bool IsCode = tsi->isText();
       Rel.SectionID = findOrEmitSection(Obj, (*tsi), IsCode, LocalSections);
@@ -899,8 +935,7 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
 }
 
 relocation_iterator RuntimeDyldELF::processRelocationRef(
-    unsigned SectionID, relocation_iterator RelI,
-    const ObjectFile &Obj,
+    unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
     ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
     StubMap &Stubs) {
   uint64_t RelType;
@@ -911,7 +946,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
 
   // Obtain the symbol name which is referenced in the relocation
   StringRef TargetName;
-  if (Symbol != Obj.symbol_end())
+  if (Symbol != Obj.end_symbols())
     Symbol->getName(TargetName);
   DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
                << " TargetName: " << TargetName << "\n");
@@ -919,7 +954,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
   // First search for the symbol in the local symbol table
   SymbolTableMap::const_iterator lsi = Symbols.end();
   SymbolRef::Type SymType = SymbolRef::ST_Unknown;
-  if (Symbol != Obj.symbol_end()) {
+  if (Symbol != Obj.end_symbols()) {
     lsi = Symbols.find(TargetName.data());
     Symbol->getType(SymType);
   }
@@ -930,7 +965,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
   } else {
     // Search for the symbol in the global symbol table
     SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end();
-    if (Symbol != Obj.symbol_end())
+    if (Symbol != Obj.end_symbols())
       gsi = GlobalSymbolTable.find(TargetName.data());
     if (gsi != GlobalSymbolTable.end()) {
       Value.SectionID = gsi->second.first;
@@ -942,9 +977,9 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
         // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
         // and can be changed by another developers. Maybe best way is add
         // a new symbol type ST_Section to SymbolRef and use it.
-        section_iterator si(Obj.section_end());
+        section_iterator si(Obj.end_sections());
         Symbol->getSection(si);
-        if (si == Obj.section_end())
+        if (si == Obj.end_sections())
           llvm_unreachable("Symbol section not found, bad object file format!");
         DEBUG(dbgs() << "\t\tThis is section symbol\n");
         bool isCode = si->isText();
@@ -1100,7 +1135,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
     if (RelType == ELF::R_PPC64_REL24) {
       // Determine ABI variant in use for this object.
       unsigned AbiVariant;
-      Obj.getPlatformFlags(AbiVariant);
+      Obj.getObjectFile()->getPlatformFlags(AbiVariant);
       AbiVariant &= ELF::EF_PPC64_ABI;
       // A PPC branch relocation will need a stub function if the target is
       // an external symbol (Symbol::ST_Unknown) or if the target address
@@ -1460,7 +1495,7 @@ uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t Offset) {
   return 0;
 }
 
-void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
+void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg,
                                   ObjSectionToIDMap &SectionMap) {
   // If necessary, allocate the global offset table
   if (MemMgr) {
@@ -1498,8 +1533,15 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
   }
 }
 
-bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const {
-  return Obj.isELF();
+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;
+}
+
+bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile *Obj) const {
+  return Obj->isELF();
 }
 
 } // namespace llvm
index f9c1d4d..4aeab81 100644 (file)
@@ -28,11 +28,9 @@ std::error_code Check(std::error_code Err) {
   }
   return Err;
 }
-
 } // end anonymous namespace
 
 class RuntimeDyldELF : public RuntimeDyldImpl {
-
   void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
                          uint64_t Value, uint32_t Type, int64_t Addend,
                          uint64_t SymOffset = 0);
@@ -83,11 +81,9 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
       return 1;
   }
 
-  void findPPC64TOCSection(const ObjectFile &Obj,
-                           ObjSectionToIDMap &LocalSections,
+  void findPPC64TOCSection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
                            RelocationValueRef &Rel);
-  void findOPDEntrySection(const ObjectFile &Obj,
-                           ObjSectionToIDMap &LocalSections,
+  void findOPDEntrySection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
                            RelocationValueRef &Rel);
 
   uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
@@ -108,23 +104,24 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
   SmallVector<SID, 2> RegisteredEHFrameSections;
 
 public:
-  RuntimeDyldELF(RTDyldMemoryManager *mm);
-  virtual ~RuntimeDyldELF();
-
-  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
-  loadObject(const object::ObjectFile &O) override;
+  RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
 
   void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
   relocation_iterator
   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
-                       const ObjectFile &Obj,
-                       ObjSectionToIDMap &ObjSectionToID,
+                       ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
                        const SymbolTableMap &Symbols, StubMap &Stubs) override;
-  bool isCompatibleFile(const object::ObjectFile &Obj) const override;
+  bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
+  bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
   void registerEHFrames() override;
   void deregisterEHFrames() override;
-  void finalizeLoad(const ObjectFile &Obj,
+  void finalizeLoad(ObjectImage &ObjImg,
                     ObjSectionToIDMap &SectionMap) override;
+  virtual ~RuntimeDyldELF();
+
+  static std::unique_ptr<ObjectImage>
+  createObjectImage(std::unique_ptr<ObjectBuffer> InputBuffer);
+  static ObjectImage *createObjectImageFromFile(std::unique_ptr<object::ObjectFile> Obj);
 };
 
 } // end namespace llvm
index 22d3940..69ea3b4 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
 #include "llvm/Object/ObjectFile.h"
@@ -36,6 +37,7 @@ using namespace llvm::object;
 
 namespace llvm {
 
+class ObjectBuffer;
 class Twine;
 
 /// SectionEntry - represents a section emitted into memory by the dynamic
@@ -157,7 +159,6 @@ public:
 };
 
 class RuntimeDyldImpl {
-  friend class RuntimeDyld::LoadedObjectInfo;
   friend class RuntimeDyldCheckerImpl;
 private:
 
@@ -295,15 +296,14 @@ protected:
   /// \brief Given the common symbols discovered in the object file, emit a
   /// new section for them and update the symbol mappings in the object and
   /// symbol table.
-  void emitCommonSymbols(const ObjectFile &Obj,
-                         const CommonSymbolMap &CommonSymbols,
+  void emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols,
                          uint64_t TotalSize, SymbolTableMap &SymbolTable);
 
   /// \brief Emits section data from the object file to the MemoryManager.
   /// \param IsCode if it's true then allocateCodeSection() will be
   ///        used for emits, else allocateDataSection() will be used.
   /// \return SectionID.
-  unsigned emitSection(const ObjectFile &Obj, const SectionRef &Section,
+  unsigned emitSection(ObjectImage &Obj, const SectionRef &Section,
                        bool IsCode);
 
   /// \brief Find Section in LocalSections. If the secton is not found - emit
@@ -311,7 +311,7 @@ protected:
   /// \param IsCode if it's true then allocateCodeSection() will be
   ///        used for emmits, else allocateDataSection() will be used.
   /// \return SectionID.
-  unsigned findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section,
+  unsigned findOrEmitSection(ObjectImage &Obj, const SectionRef &Section,
                              bool IsCode, ObjSectionToIDMap &LocalSections);
 
   // \brief Add a relocation entry that uses the given section.
@@ -339,7 +339,7 @@ protected:
   /// \return Iterator to the next relocation that needs to be parsed.
   virtual relocation_iterator
   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
-                       const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID,
+                       ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
                        const SymbolTableMap &Symbols, StubMap &Stubs) = 0;
 
   /// \brief Resolve relocations to external symbols.
@@ -351,16 +351,13 @@ protected:
 
   // \brief Compute an upper bound of the memory that is required to load all
   // sections
-  void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize,
+  void computeTotalAllocSize(ObjectImage &Obj, uint64_t &CodeSize,
                              uint64_t &DataSizeRO, uint64_t &DataSizeRW);
 
   // \brief Compute the stub buffer size required for a section
-  unsigned computeSectionStubBufSize(const ObjectFile &Obj,
+  unsigned computeSectionStubBufSize(ObjectImage &Obj,
                                      const SectionRef &Section);
 
-  // \brief Implementation of the generic part of the loadObject algorithm.
-  std::pair<unsigned, unsigned> loadObjectImpl(const object::ObjectFile &Obj);
-
 public:
   RuntimeDyldImpl(RTDyldMemoryManager *mm)
     : MemMgr(mm), Checker(nullptr), ProcessAllSections(false), HasError(false) {
@@ -376,8 +373,8 @@ public:
     this->Checker = Checker;
   }
 
-  virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
-  loadObject(const object::ObjectFile &Obj) = 0;
+  std::unique_ptr<ObjectImage>
+  loadObject(std::unique_ptr<ObjectImage> InputObject);
 
   uint8_t* getSymbolAddress(StringRef Name) const {
     // FIXME: Just look up as a function for now. Overly simple of course.
@@ -414,14 +411,14 @@ public:
   // Get the error message.
   StringRef getErrorString() { return ErrorStr; }
 
-  virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0;
+  virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0;
+  virtual bool isCompatibleFile(const ObjectFile *Obj) const = 0;
 
   virtual void registerEHFrames();
 
   virtual void deregisterEHFrames();
 
-  virtual void finalizeLoad(const ObjectFile &ObjImg,
-                            ObjSectionToIDMap &SectionMap) {}
+  virtual void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) {}
 };
 
 } // end namespace llvm
index 81020dc..d3d6f5d 100644 (file)
@@ -25,22 +25,6 @@ using namespace llvm::object;
 
 #define DEBUG_TYPE "dyld"
 
-namespace {
-
-class LoadedMachOObjectInfo : public RuntimeDyld::LoadedObjectInfo {
-public:
-  LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
-                        unsigned EndIdx)
-    : RuntimeDyld::LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {}
-
-  OwningBinary<ObjectFile>
-  getObjectForDebug(const ObjectFile &Obj) const override {
-    return OwningBinary<ObjectFile>();
-  }
-};
-
-}
-
 namespace llvm {
 
 int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const {
@@ -51,12 +35,12 @@ int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const {
 }
 
 RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
-    const ObjectFile &BaseTObj, const relocation_iterator &RI,
+    ObjectImage &ObjImg, const relocation_iterator &RI,
     const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID,
     const SymbolTableMap &Symbols) {
 
   const MachOObjectFile &Obj =
-      static_cast<const MachOObjectFile &>(BaseTObj);
+      static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
   MachO::any_relocation_info RelInfo =
       Obj.getRelocation(RI->getRawDataRefImpl());
   RelocationValueRef Value;
@@ -83,7 +67,7 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
   } else {
     SectionRef Sec = Obj.getRelocationSection(RelInfo);
     bool IsCode = Sec.isText();
-    Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID);
+    Value.SectionID = findOrEmitSection(ObjImg, Sec, IsCode, ObjSectionToID);
     uint64_t Addr = Sec.getAddress();
     Value.Offset = RE.Addend - Addr;
   }
@@ -92,11 +76,11 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
 }
 
 void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value,
-                                            const ObjectFile &BaseTObj,
+                                            ObjectImage &ObjImg,
                                             const relocation_iterator &RI,
                                             unsigned OffsetToNextPC) {
   const MachOObjectFile &Obj =
-      static_cast<const MachOObjectFile &>(BaseTObj);
+      static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
   MachO::any_relocation_info RelInfo =
       Obj.getRelocation(RI->getRawDataRefImpl());
 
@@ -141,7 +125,7 @@ RuntimeDyldMachO::getSectionByAddress(const MachOObjectFile &Obj,
 
 // Populate __pointers section.
 void RuntimeDyldMachO::populateIndirectSymbolPointersSection(
-                                                    const MachOObjectFile &Obj,
+                                                    MachOObjectFile &Obj,
                                                     const SectionRef &PTSection,
                                                     unsigned PTSectionID) {
   assert(!Obj.is64Bit() &&
@@ -179,12 +163,28 @@ void RuntimeDyldMachO::populateIndirectSymbolPointersSection(
   }
 }
 
-bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile &Obj) const {
-  return Obj.isMachO();
+bool
+RuntimeDyldMachO::isCompatibleFormat(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;
+  if (Magic == "\xCF\xFA\xED\xFE")
+    return true;
+  return false;
+}
+
+bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile *Obj) const {
+  return Obj->isMachO();
 }
 
 template <typename Impl>
-void RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &ObjImg,
+void RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(ObjectImage &ObjImg,
                                                   ObjSectionToIDMap &SectionMap) {
   unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
   unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
@@ -284,7 +284,7 @@ void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {
 }
 
 std::unique_ptr<RuntimeDyldMachO>
-RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
+llvm::RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
   switch (Arch) {
   default:
     llvm_unreachable("Unsupported target for RuntimeDyldMachO.");
@@ -296,12 +296,4 @@ RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
   }
 }
 
-std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
-RuntimeDyldMachO::loadObject(const object::ObjectFile &O) {
-  unsigned SectionStartIdx, SectionEndIdx;
-  std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O);
-  return llvm::make_unique<LoadedMachOObjectInfo>(*this, SectionStartIdx,
-                                                  SectionEndIdx);
-}
-
 } // end namespace llvm
index ff102ff..7583474 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDMACHO_H
 #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDMACHO_H
 
+#include "ObjectImageCommon.h"
 #include "RuntimeDyldImpl.h"
 #include "llvm/Object/MachO.h"
 #include "llvm/Support/Format.h"
@@ -60,11 +61,10 @@ protected:
   /// filled in, since immediate encodings are highly target/opcode specific.
   /// For targets/opcodes with simple, contiguous immediates (e.g. X86) the
   /// memcpyAddend method can be used to read the immediate.
-  RelocationEntry getRelocationEntry(unsigned SectionID,
-                                     const ObjectFile &BaseTObj,
+  RelocationEntry getRelocationEntry(unsigned SectionID, ObjectImage &ObjImg,
                                      const relocation_iterator &RI) const {
     const MachOObjectFile &Obj =
-      static_cast<const MachOObjectFile &>(BaseTObj);
+      static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
     MachO::any_relocation_info RelInfo =
       Obj.getRelocation(RI->getRawDataRefImpl());
 
@@ -87,15 +87,14 @@ protected:
   /// In both cases the Addend field is *NOT* fixed up to be PC-relative. That
   /// should be done by the caller where appropriate by calling makePCRel on
   /// the RelocationValueRef.
-  RelocationValueRef getRelocationValueRef(const ObjectFile &BaseTObj,
+  RelocationValueRef getRelocationValueRef(ObjectImage &ObjImg,
                                            const relocation_iterator &RI,
                                            const RelocationEntry &RE,
                                            ObjSectionToIDMap &ObjSectionToID,
                                            const SymbolTableMap &Symbols);
 
   /// Make the RelocationValueRef addend PC-relative.
-  void makeValueAddendPCRel(RelocationValueRef &Value,
-                            const ObjectFile &BaseTObj,
+  void makeValueAddendPCRel(RelocationValueRef &Value, ObjectImage &ObjImg,
                             const relocation_iterator &RI,
                             unsigned OffsetToNextPC);
 
@@ -108,22 +107,31 @@ protected:
 
 
   // Populate __pointers section.
-  void populateIndirectSymbolPointersSection(const MachOObjectFile &Obj,
+  void populateIndirectSymbolPointersSection(MachOObjectFile &Obj,
                                              const SectionRef &PTSection,
                                              unsigned PTSectionID);
 
 public:
+  /// Create an ObjectImage from the given ObjectBuffer.
+  static std::unique_ptr<ObjectImage>
+  createObjectImage(std::unique_ptr<ObjectBuffer> InputBuffer) {
+    return llvm::make_unique<ObjectImageCommon>(std::move(InputBuffer));
+  }
+
+  /// Create an ObjectImage from the given ObjectFile.
+  static ObjectImage *
+  createObjectImageFromFile(std::unique_ptr<object::ObjectFile> InputObject) {
+    return new ObjectImageCommon(std::move(InputObject));
+  }
 
   /// Create a RuntimeDyldMachO instance for the given target architecture.
   static std::unique_ptr<RuntimeDyldMachO> create(Triple::ArchType Arch,
                                                   RTDyldMemoryManager *mm);
 
-  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
-  loadObject(const object::ObjectFile &O) override;
-
   SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
 
-  bool isCompatibleFile(const object::ObjectFile &Obj) const override;
+  bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
+  bool isCompatibleFile(const object::ObjectFile *Obj) const override;
 };
 
 /// RuntimeDyldMachOTarget - Templated base class for generic MachO linker
@@ -145,7 +153,7 @@ private:
 public:
   RuntimeDyldMachOCRTPBase(RTDyldMemoryManager *mm) : RuntimeDyldMachO(mm) {}
 
-  void finalizeLoad(const ObjectFile &Obj,
+  void finalizeLoad(ObjectImage &ObjImg,
                     ObjSectionToIDMap &SectionMap) override;
   void registerEHFrames() override;
 };
index 8c1efef..f5cf9ac 100644 (file)
@@ -243,11 +243,10 @@ public:
 
   relocation_iterator
   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
-                       const ObjectFile &BaseObjT,
-                       ObjSectionToIDMap &ObjSectionToID,
+                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
                        const SymbolTableMap &Symbols, StubMap &Stubs) override {
     const MachOObjectFile &Obj =
-      static_cast<const MachOObjectFile &>(BaseObjT);
+        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
     MachO::any_relocation_info RelInfo =
         Obj.getRelocation(RelI->getRawDataRefImpl());
 
@@ -269,10 +268,10 @@ public:
       RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl());
     }
 
-    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
+    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
     RE.Addend = decodeAddend(RE);
     RelocationValueRef Value(
-        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols));
+        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
 
     assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\
       "ARM64_RELOC_ADDEND and embedded addend in the instruction.");
@@ -283,7 +282,7 @@ public:
 
     bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
     if (!IsExtern && RE.IsPCRel)
-      makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size);
+      makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size);
 
     RE.Addend = Value.Offset;
 
@@ -360,7 +359,7 @@ public:
     }
   }
 
-  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
+  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
                        const SectionRef &Section) {}
 
 private:
index d7e6236..9766751 100644 (file)
@@ -49,30 +49,29 @@ public:
 
   relocation_iterator
   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
-                       const ObjectFile &BaseObjT,
-                       ObjSectionToIDMap &ObjSectionToID,
+                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
                        const SymbolTableMap &Symbols, StubMap &Stubs) override {
     const MachOObjectFile &Obj =
-        static_cast<const MachOObjectFile &>(BaseObjT);
+        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
     MachO::any_relocation_info RelInfo =
         Obj.getRelocation(RelI->getRawDataRefImpl());
     uint32_t RelType = Obj.getAnyRelocationType(RelInfo);
 
     if (Obj.isRelocationScattered(RelInfo)) {
       if (RelType == MachO::ARM_RELOC_HALF_SECTDIFF)
-        return processHALFSECTDIFFRelocation(SectionID, RelI, Obj,
+        return processHALFSECTDIFFRelocation(SectionID, RelI, ObjImg,
                                              ObjSectionToID);
       else
         return ++++RelI;
     }
 
-    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
+    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
     RE.Addend = decodeAddend(RE);
     RelocationValueRef Value(
-        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols));
+        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
 
     if (RE.IsPCRel)
-      makeValueAddendPCRel(Value, Obj, RelI, 8);
+      makeValueAddendPCRel(Value, ObjImg, RelI, 8);
 
     if ((RE.RelType & 0xf) == MachO::ARM_RELOC_BR24)
       processBranchRelocation(RE, Value, Stubs);
@@ -155,14 +154,15 @@ public:
     }
   }
 
-  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
+  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
                        const SectionRef &Section) {
     StringRef Name;
     Section.getName(Name);
 
     if (Name == "__nl_symbol_ptr")
-      populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj),
-                                            Section, SectionID);
+      populateIndirectSymbolPointersSection(
+                                 cast<MachOObjectFile>(*ObjImg.getObjectFile()),
+                                 Section, SectionID);
   }
 
 private:
@@ -199,25 +199,25 @@ private:
 
   relocation_iterator
   processHALFSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,
-                                const ObjectFile &BaseTObj,
+                                ObjectImage &Obj,
                                 ObjSectionToIDMap &ObjSectionToID) {
-    const MachOObjectFile &MachO =
-        static_cast<const MachOObjectFile&>(BaseTObj);
+    const MachOObjectFile *MachO =
+        static_cast<const MachOObjectFile *>(Obj.getObjectFile());
     MachO::any_relocation_info RE =
-        MachO.getRelocation(RelI->getRawDataRefImpl());
+        MachO->getRelocation(RelI->getRawDataRefImpl());
 
 
     // For a half-diff relocation the length bits actually record whether this
     // is a movw/movt, and whether this is arm or thumb.
     // Bit 0 indicates movw (b0 == 0) or movt (b0 == 1).
     // Bit 1 indicates arm (b1 == 0) or thumb (b1 == 1).
-    unsigned HalfDiffKindBits = MachO.getAnyRelocationLength(RE);
+    unsigned HalfDiffKindBits = MachO->getAnyRelocationLength(RE);
     if (HalfDiffKindBits & 0x2)
       llvm_unreachable("Thumb not yet supported.");
 
     SectionEntry &Section = Sections[SectionID];
-    uint32_t RelocType = MachO.getAnyRelocationType(RE);
-    bool IsPCRel = MachO.getAnyRelocationPCRel(RE);
+    uint32_t RelocType = MachO->getAnyRelocationType(RE);
+    bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
     uint64_t Offset;
     RelI->getOffset(Offset);
     uint8_t *LocalAddress = Section.Address + Offset;
@@ -226,27 +226,27 @@ private:
 
     ++RelI;
     MachO::any_relocation_info RE2 =
-      MachO.getRelocation(RelI->getRawDataRefImpl());
-    uint32_t AddrA = MachO.getScatteredRelocationValue(RE);
-    section_iterator SAI = getSectionByAddress(MachO, AddrA);
-    assert(SAI != MachO.section_end() && "Can't find section for address A");
+        MachO->getRelocation(RelI->getRawDataRefImpl());
+    uint32_t AddrA = MachO->getScatteredRelocationValue(RE);
+    section_iterator SAI = getSectionByAddress(*MachO, AddrA);
+    assert(SAI != MachO->section_end() && "Can't find section for address A");
     uint64_t SectionABase = SAI->getAddress();
     uint64_t SectionAOffset = AddrA - SectionABase;
     SectionRef SectionA = *SAI;
     bool IsCode = SectionA.isText();
     uint32_t SectionAID =
-        findOrEmitSection(MachO, SectionA, IsCode, ObjSectionToID);
+        findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID);
 
-    uint32_t AddrB = MachO.getScatteredRelocationValue(RE2);
-    section_iterator SBI = getSectionByAddress(MachO, AddrB);
-    assert(SBI != MachO.section_end() && "Can't find section for address B");
+    uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
+    section_iterator SBI = getSectionByAddress(*MachO, AddrB);
+    assert(SBI != MachO->section_end() && "Can't find section for address B");
     uint64_t SectionBBase = SBI->getAddress();
     uint64_t SectionBOffset = AddrB - SectionBBase;
     SectionRef SectionB = *SBI;
     uint32_t SectionBID =
-        findOrEmitSection(MachO, SectionB, IsCode, ObjSectionToID);
+        findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID);
 
-    uint32_t OtherHalf = MachO.getAnyRelocationAddress(RE2) & 0xffff;
+    uint32_t OtherHalf = MachO->getAnyRelocationAddress(RE2) & 0xffff;
     unsigned Shift = (HalfDiffKindBits & 0x1) ? 16 : 0;
     uint32_t FullImmVal = (Immediate << Shift) | (OtherHalf << (16 - Shift));
     int64_t Addend = FullImmVal - (AddrA - AddrB);
index 78ac911..258b847 100644 (file)
@@ -31,11 +31,10 @@ public:
 
   relocation_iterator
   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
-                       const ObjectFile &BaseObjT,
-                       ObjSectionToIDMap &ObjSectionToID,
+                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
                        const SymbolTableMap &Symbols, StubMap &Stubs) override {
     const MachOObjectFile &Obj =
-        static_cast<const MachOObjectFile &>(BaseObjT);
+        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
     MachO::any_relocation_info RelInfo =
         Obj.getRelocation(RelI->getRawDataRefImpl());
     uint32_t RelType = Obj.getAnyRelocationType(RelInfo);
@@ -43,18 +42,18 @@ public:
     if (Obj.isRelocationScattered(RelInfo)) {
       if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
           RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
-        return processSECTDIFFRelocation(SectionID, RelI, Obj,
+        return processSECTDIFFRelocation(SectionID, RelI, ObjImg,
                                          ObjSectionToID);
       else if (RelType == MachO::GENERIC_RELOC_VANILLA)
-        return processI386ScatteredVANILLA(SectionID, RelI, Obj,
+        return processI386ScatteredVANILLA(SectionID, RelI, ObjImg,
                                            ObjSectionToID);
       llvm_unreachable("Unhandled scattered relocation.");
     }
 
-    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
+    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
     RE.Addend = memcpyAddend(RE);
     RelocationValueRef Value(
-        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols));
+        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
 
     // Addends for external, PC-rel relocations on i386 point back to the zero
     // offset. Calculate the final offset from the relocation target instead.
@@ -67,7 +66,7 @@ public:
     //   Value.Addend += RelocAddr + 4;
     // }
     if (RE.IsPCRel)
-      makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size);
+      makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size);
 
     RE.Addend = Value.Offset;
 
@@ -111,32 +110,34 @@ public:
     }
   }
 
-  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
+  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
                        const SectionRef &Section) {
     StringRef Name;
     Section.getName(Name);
 
     if (Name == "__jump_table")
-      populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID);
+      populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()), Section,
+                        SectionID);
     else if (Name == "__pointers")
-      populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj),
-                                            Section, SectionID);
+      populateIndirectSymbolPointersSection(
+                                 cast<MachOObjectFile>(*ObjImg.getObjectFile()),
+                                 Section, SectionID);
   }
 
 private:
   relocation_iterator
   processSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,
-                            const ObjectFile &BaseObjT,
+                            ObjectImage &Obj,
                             ObjSectionToIDMap &ObjSectionToID) {
-    const MachOObjectFile &Obj =
-        static_cast<const MachOObjectFile&>(BaseObjT);
+    const MachOObjectFile *MachO =
+        static_cast<const MachOObjectFile *>(Obj.getObjectFile());
     MachO::any_relocation_info RE =
-        Obj.getRelocation(RelI->getRawDataRefImpl());
+        MachO->getRelocation(RelI->getRawDataRefImpl());
 
     SectionEntry &Section = Sections[SectionID];
-    uint32_t RelocType = Obj.getAnyRelocationType(RE);
-    bool IsPCRel = Obj.getAnyRelocationPCRel(RE);
-    unsigned Size = Obj.getAnyRelocationLength(RE);
+    uint32_t RelocType = MachO->getAnyRelocationType(RE);
+    bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
+    unsigned Size = MachO->getAnyRelocationLength(RE);
     uint64_t Offset;
     RelI->getOffset(Offset);
     uint8_t *LocalAddress = Section.Address + Offset;
@@ -145,11 +146,11 @@ private:
 
     ++RelI;
     MachO::any_relocation_info RE2 =
-        Obj.getRelocation(RelI->getRawDataRefImpl());
+        MachO->getRelocation(RelI->getRawDataRefImpl());
 
-    uint32_t AddrA = Obj.getScatteredRelocationValue(RE);
-    section_iterator SAI = getSectionByAddress(Obj, AddrA);
-    assert(SAI != Obj.section_end() && "Can't find section for address A");
+    uint32_t AddrA = MachO->getScatteredRelocationValue(RE);
+    section_iterator SAI = getSectionByAddress(*MachO, AddrA);
+    assert(SAI != MachO->section_end() && "Can't find section for address A");
     uint64_t SectionABase = SAI->getAddress();
     uint64_t SectionAOffset = AddrA - SectionABase;
     SectionRef SectionA = *SAI;
@@ -157,9 +158,9 @@ private:
     uint32_t SectionAID =
         findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID);
 
-    uint32_t AddrB = Obj.getScatteredRelocationValue(RE2);
-    section_iterator SBI = getSectionByAddress(Obj, AddrB);
-    assert(SBI != Obj.section_end() && "Can't find section for address B");
+    uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
+    section_iterator SBI = getSectionByAddress(*MachO, AddrB);
+    assert(SBI != MachO->section_end() && "Can't find section for address B");
     uint64_t SectionBBase = SBI->getAddress();
     uint64_t SectionBOffset = AddrB - SectionBBase;
     SectionRef SectionB = *SBI;
@@ -185,27 +186,26 @@ private:
   }
 
   relocation_iterator processI386ScatteredVANILLA(
-      unsigned SectionID, relocation_iterator RelI,
-      const ObjectFile &BaseObjT,
+      unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
       RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID) {
-    const MachOObjectFile &Obj =
-        static_cast<const MachOObjectFile&>(BaseObjT);
+    const MachOObjectFile *MachO =
+        static_cast<const MachOObjectFile *>(Obj.getObjectFile());
     MachO::any_relocation_info RE =
-        Obj.getRelocation(RelI->getRawDataRefImpl());
+        MachO->getRelocation(RelI->getRawDataRefImpl());
 
     SectionEntry &Section = Sections[SectionID];
-    uint32_t RelocType = Obj.getAnyRelocationType(RE);
-    bool IsPCRel = Obj.getAnyRelocationPCRel(RE);
-    unsigned Size = Obj.getAnyRelocationLength(RE);
+    uint32_t RelocType = MachO->getAnyRelocationType(RE);
+    bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
+    unsigned Size = MachO->getAnyRelocationLength(RE);
     uint64_t Offset;
     RelI->getOffset(Offset);
     uint8_t *LocalAddress = Section.Address + Offset;
     unsigned NumBytes = 1 << Size;
     int64_t Addend = readBytesUnaligned(LocalAddress, NumBytes);
 
-    unsigned SymbolBaseAddr = Obj.getScatteredRelocationValue(RE);
-    section_iterator TargetSI = getSectionByAddress(Obj, SymbolBaseAddr);
-    assert(TargetSI != Obj.section_end() && "Can't find section for symbol");
+    unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE);
+    section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr);
+    assert(TargetSI != MachO->section_end() && "Can't find section for symbol");
     uint64_t SectionBaseAddr = TargetSI->getAddress();
     SectionRef TargetSection = *TargetSI;
     bool IsCode = TargetSection.isText();
@@ -221,7 +221,7 @@ private:
   }
 
   // Populate stubs in __jump_table section.
-  void populateJumpTable(const MachOObjectFile &Obj, const SectionRef &JTSection,
+  void populateJumpTable(MachOObjectFile &Obj, const SectionRef &JTSection,
                          unsigned JTSectionID) {
     assert(!Obj.is64Bit() &&
            "__jump_table section not supported in 64-bit MachO.");
index a38867e..84d9e80 100644 (file)
@@ -31,25 +31,24 @@ public:
 
   relocation_iterator
   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
-                       const ObjectFile &BaseObjT,
-                       ObjSectionToIDMap &ObjSectionToID,
+                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
                        const SymbolTableMap &Symbols, StubMap &Stubs) override {
     const MachOObjectFile &Obj =
-      static_cast<const MachOObjectFile &>(BaseObjT);
+        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
     MachO::any_relocation_info RelInfo =
         Obj.getRelocation(RelI->getRawDataRefImpl());
 
     assert(!Obj.isRelocationScattered(RelInfo) &&
            "Scattered relocations not supported on X86_64");
 
-    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
+    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
     RE.Addend = memcpyAddend(RE);
     RelocationValueRef Value(
-        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols));
+        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
 
     bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
     if (!IsExtern && RE.IsPCRel)
-      makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size);
+      makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size);
 
     if (RE.RelType == MachO::X86_64_RELOC_GOT ||
         RE.RelType == MachO::X86_64_RELOC_GOT_LOAD)
@@ -98,7 +97,7 @@ public:
     }
   }
 
-  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
+  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
                        const SectionRef &Section) {}
 
 private:
index 47da8fb..5a135ea 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "RemoteMemoryManager.h"
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Format.h"
 
@@ -77,7 +78,7 @@ sys::MemoryBlock RemoteMemoryManager::allocateSection(uintptr_t Size) {
 }
 
 void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE,
-                                             const object::ObjectFile &Obj) {
+                                                const ObjectImage *Obj) {
   // The client should have called setRemoteTarget() before triggering any
   // code generation.
   assert(Target);
index 895bcda..0bdb4e2 100644 (file)
@@ -80,8 +80,7 @@ public:
   // symbols from Modules it contains.
   uint64_t getSymbolAddress(const std::string &Name) override { return 0; }
 
-  void notifyObjectLoaded(ExecutionEngine *EE,
-                          const object::ObjectFile &Obj) override;
+  void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj) override;
 
   bool finalizeMemory(std::string *ErrMsg) override;
 
index 0f85a85..0bb6e8b 100644 (file)
 #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"
index c38e423..87d381e 100644 (file)
@@ -13,6 +13,8 @@
 
 #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"
@@ -205,32 +207,23 @@ static int printLineInfoForInput() {
     if (std::error_code EC = InputBuffer.getError())
       return Error("unable to read input: '" + EC.message() + "'");
 
-    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;
-
+    std::unique_ptr<ObjectImage> LoadedObject;
     // Load the object file
-    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo =
-      Dyld.loadObject(Obj);
-
-    if (Dyld.hasError())
+    LoadedObject = Dyld.loadObject(
+        llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
+    if (!LoadedObject) {
       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(*DebugObj.getBinary()));
+        DIContext::getDWARFContext(*LoadedObject->getObjectFile()));
 
     // Use symbol info to iterate functions in the object.
-    for (object::symbol_iterator I = DebugObj.getBinary()->symbol_begin(),
-                                 E = DebugObj.getBinary()->symbol_end();
+    for (object::symbol_iterator I = LoadedObject->begin_symbols(),
+                                 E = LoadedObject->end_symbols();
          I != E; ++I) {
       object::SymbolRef::Type SymType;
       if (I->getType(SymType)) continue;
@@ -275,17 +268,11 @@ static int executeInput() {
         MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
     if (std::error_code EC = InputBuffer.getError())
       return Error("unable to read input: '" + EC.message() + "'");
-    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;
-
+    std::unique_ptr<ObjectImage> LoadedObject;
     // Load the object file
-    Dyld.loadObject(Obj);
-    if (Dyld.hasError()) {
+    LoadedObject = Dyld.loadObject(
+        llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
+    if (!LoadedObject) {
       return Error(Dyld.getErrorString());
     }
   }
@@ -525,21 +512,14 @@ static int linkAndVerify() {
     // 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() + "'");
 
-    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;
-
+    std::unique_ptr<ObjectImage> LoadedObject;
     // Load the object file
-    Dyld.loadObject(Obj);
-    if (Dyld.hasError()) {
+    LoadedObject = Dyld.loadObject(
+        llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
+    if (!LoadedObject) {
       return Error(Dyld.getErrorString());
     }
   }