[llvm] r222810 - [MCJIT] Clean up RuntimeDyld's quirky object-ownership/modification scheme.

Aaron Ballman aaron at aaronballman.com
Wed Nov 26 07:28:23 PST 2014


To get the build working again on Windows, I have reverted r222828 and
r222810-r222812. Sorry! (This was commit r222833.)

~Aaron


On Wed, Nov 26, 2014 at 9:49 AM, Aaron Ballman <aaron at aaronballman.com> wrote:
> On Wed, Nov 26, 2014 at 1:53 AM, Lang Hames <lhames at gmail.com> wrote:
>> Author: lhames
>> Date: Wed Nov 26 00:53:26 2014
>> New Revision: 222810
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=222810&view=rev
>> Log:
>> [MCJIT] Clean up RuntimeDyld's quirky object-ownership/modification scheme.
>>
>> Previously, when loading an object file, RuntimeDyld (1) took ownership of the
>> ObjectFile instance (and associated MemoryBuffer), (2) potentially modified the
>> object in-place, and (3) returned an ObjectImage that managed ownership of the
>> now-modified object and provided some convenience methods. This scheme accreted
>> over several years as features were tacked on to RuntimeDyld, and was both
>> unintuitive and unsafe (See e.g. http://llvm.org/PR20722).
>>
>> This patch fixes the issue by removing all ownership and in-place modification
>> of object files from RuntimeDyld. Existing behavior, including debugger
>> registration, is preserved.
>>
>> Noteworthy changes include:
>>
>> (1) ObjectFile instances are now passed to RuntimeDyld by const-ref.
>> (2) The ObjectImage and ObjectBuffer classes have been removed entirely, they
>>     existed to model ownership within RuntimeDyld, and so are no longer needed.
>> (3) RuntimeDyld::loadObject now returns an instance of a new class,
>>     RuntimeDyld::LoadedObjectInfo, which can be used to construct a modified
>>     object suitable for registration with the debugger, following the existing
>>     debugger registration scheme.
>> (4) The JITRegistrar class has been removed, and the GDBRegistrar class has been
>>     re-written as a JITEventListener.
>>
>> This should fix http://llvm.org/PR20722 .
>>
>>
>> Added:
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h
>>       - copied, changed from r222801, llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp
>>       - copied, changed from r222764, llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>> Removed:
>>     llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>>     llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
>>     llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
>> Modified:
>>     llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
>>     llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
>>     llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
>>     llvm/trunk/lib/ExecutionEngine/CMakeLists.txt
>>     llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
>>     llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>>     llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
>>     llvm/trunk/tools/lli/RemoteMemoryManager.cpp
>>     llvm/trunk/tools/lli/RemoteMemoryManager.h
>>     llvm/trunk/tools/llvm-jitlistener/llvm-jitlistener.cpp
>>     llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h Wed Nov 26 00:53:26 2014
>> @@ -15,6 +15,7 @@
>>  #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"
>> @@ -25,7 +26,10 @@ class Function;
>>  class MachineFunction;
>>  class OProfileWrapper;
>>  class IntelJITEventsWrapper;
>> -class ObjectImage;
>> +
>> +namespace object {
>> +  class ObjectFile;
>> +}
>>
>>  /// JITEvent_EmittedFunctionDetails - Helper struct for containing information
>>  /// about a generated machine code function.
>> @@ -57,7 +61,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
>> @@ -67,11 +71,15 @@ 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 ObjectImage &Obj) {}
>> +  virtual void NotifyObjectEmitted(const object::ObjectFile &Obj,
>> +                                   const RuntimeDyld::LoadedObjectInfo &L) {}
>>
>>    /// NotifyFreeingObject - Called just before the memory associated with
>>    /// a previously emitted object is released.
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
>> +  virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {}
>> +
>> +  // Get a pointe to the GDB debugger registration listener.
>> +  static JITEventListener *createGDBRegistrationListener();
>>
>>  #if LLVM_USE_INTEL_JITEVENTS
>>    // Construct an IntelJITEventListener
>> @@ -105,7 +113,8 @@ public:
>>      return nullptr;
>>    }
>>  #endif // USE_OPROFILE
>> -
>> +private:
>> +  virtual void anchor();
>>  };
>>
>>  } // end namespace llvm.
>>
>> Removed: llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (removed)
>> @@ -1,76 +0,0 @@
>> -//===---- 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
>>
>> Removed: llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h (removed)
>> @@ -1,76 +0,0 @@
>> -//===---- 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
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h Wed Nov 26 00:53:26 2014
>> @@ -22,7 +22,10 @@
>>  namespace llvm {
>>
>>  class ExecutionEngine;
>> -class ObjectImage;
>> +
>> +  namespace object {
>> +    class ObjectFile;
>> +  }
>>
>>  // RuntimeDyld clients often want to handle the memory management of
>>  // what gets placed where. For JIT clients, this is the subset of
>> @@ -109,7 +112,7 @@ public:
>>    /// address space can use this call to remap the section addresses for the
>>    /// newly loaded object.
>>    virtual void notifyObjectLoaded(ExecutionEngine *EE,
>> -                                  const ObjectImage *) {}
>> +                                  const object::ObjectFile &) {}
>>
>>    /// This method is called when object loading is complete and section page
>>    /// permissions can be applied.  It is up to the memory manager implementation
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Wed Nov 26 00:53:26 2014
>> @@ -15,19 +15,19 @@
>>  #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,22 +46,35 @@ 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();
>>
>> -  /// 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);
>> +  /// Add the referenced object file to the list of objects to be loaded and
>> +  /// relocated.
>> +  std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O);
>>
>>    /// 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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/CMakeLists.txt?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/ExecutionEngine/CMakeLists.txt Wed Nov 26 00:53:26 2014
>> @@ -3,7 +3,6 @@
>>  add_llvm_library(LLVMExecutionEngine
>>    ExecutionEngine.cpp
>>    ExecutionEngineBindings.cpp
>> -  JITEventListener.cpp
>>    RTDyldMemoryManager.cpp
>>    TargetSelect.cpp
>>    )
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Wed Nov 26 00:53:26 2014
>> @@ -16,8 +16,7 @@
>>  #include "llvm/ADT/SmallString.h"
>>  #include "llvm/ADT/Statistic.h"
>>  #include "llvm/ExecutionEngine/GenericValue.h"
>> -#include "llvm/ExecutionEngine/ObjectBuffer.h"
>> -#include "llvm/ExecutionEngine/ObjectCache.h"
>> +#include "llvm/ExecutionEngine/JITEventListener.h"
>>  #include "llvm/IR/Constants.h"
>>  #include "llvm/IR/DataLayout.h"
>>  #include "llvm/IR/DerivedTypes.h"
>> @@ -43,17 +42,15 @@ 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) {
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -21,7 +21,6 @@
>>  #include "llvm/ADT/DenseMap.h"
>>  #include "llvm/CodeGen/MachineFunction.h"
>>  #include "llvm/DebugInfo/DIContext.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>>  #include "llvm/Object/ObjectFile.h"
>>  #include "llvm/Support/Debug.h"
>>  #include "llvm/Support/raw_ostream.h"
>> @@ -32,6 +31,7 @@
>>
>>  using namespace llvm;
>>  using namespace llvm::jitprofiling;
>> +using namespace llvm::object;
>>
>>  #define DEBUG_TYPE "amplifier-jit-event-listener"
>>
>> @@ -48,6 +48,7 @@ class IntelJITEventListener : public JIT
>>    typedef DenseMap<const void *, MethodAddressVector>  ObjectMap;
>>
>>    ObjectMap  LoadedObjectMap;
>> +  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
>>
>>  public:
>>    IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
>> @@ -57,9 +58,10 @@ public:
>>    ~IntelJITEventListener() {
>>    }
>>
>> -  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
>> +  void NotifyObjectEmitted(const ObjectFile &Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L) override;
>>
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj);
>> +  void NotifyFreeingObject(const ObjectFile &Obj) override;
>>  };
>>
>>  static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress,
>> @@ -95,23 +97,29 @@ static iJIT_Method_Load FunctionDescToIn
>>    return Result;
>>  }
>>
>> -void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
>> +void IntelJITEventListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Obj,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +
>> +  OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
>> +  const ObjectFile &DebugObj = *DebugObjOwner.getBinary();
>> +
>>    // Get the address of the object image for use as a unique identifier
>> -  const void* ObjData = Obj.getData().data();
>> -  DIContext* Context = DIContext::getDWARFContext(*Obj.getObjectFile());
>> +  const void* ObjData = DebugObj.getData().data();
>> +  DIContext* Context = DIContext::getDWARFContext(DebugObj);
>>    MethodAddressVector Functions;
>>
>>    // Use symbol info to iterate functions in the object.
>> -  for (object::symbol_iterator I = Obj.begin_symbols(),
>> -                               E = Obj.end_symbols();
>> +  for (symbol_iterator I = DebugObj.symbol_begin(),
>> +                       E = DebugObj.symbol_end();
>>                          I != E;
>>                          ++I) {
>>      std::vector<LineNumberInfo> LineInfo;
>>      std::string SourceFileName;
>>
>> -    object::SymbolRef::Type SymType;
>> +    SymbolRef::Type SymType;
>>      if (I->getType(SymType)) continue;
>> -    if (SymType == object::SymbolRef::ST_Function) {
>> +    if (SymType == SymbolRef::ST_Function) {
>>        StringRef  Name;
>>        uint64_t   Addr;
>>        uint64_t   Size;
>> @@ -162,11 +170,18 @@ void IntelJITEventListener::NotifyObject
>>    // registered function addresses for each loaded object.  We will
>>    // use the MethodIDs map to get the registered ID for each function.
>>    LoadedObjectMap[ObjData] = Functions;
>> +  DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
>>  }
>>
>> -void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
>> +void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
>> +  // This object may not have been registered with the listener. If it wasn't,
>> +  // bail out.
>> +  if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end())
>> +    return;
>> +
>>    // Get the address of the object image for use as a unique identifier
>> -  const void* ObjData = Obj.getData().data();
>> +  const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary();
>> +  const void* ObjData = DebugObj.getData().data();
>>
>>    // Get the object's function list from LoadedObjectMap
>>    ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
>> @@ -190,6 +205,7 @@ void IntelJITEventListener::NotifyFreein
>>
>>    // Erase the object from LoadedObjectMap
>>    LoadedObjectMap.erase(OI);
>> +  DebugObjects.erase(Obj.getData().data());
>>  }
>>
>>  }  // anonymous namespace.
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp (removed)
>> @@ -1,15 +0,0 @@
>> -//===-- 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() {}
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Wed Nov 26 00:53:26 2014
>> @@ -11,8 +11,6 @@
>>  #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"
>> @@ -21,6 +19,7 @@
>>  #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"
>> @@ -31,6 +30,8 @@
>>
>>  using namespace llvm;
>>
>> +void ObjectCache::anchor() {}
>> +
>>  namespace {
>>
>>  static struct RegisterJIT {
>> @@ -74,6 +75,7 @@ MCJIT::MCJIT(std::unique_ptr<Module> M,
>>
>>    OwnedModules.addModule(std::move(First));
>>    setDataLayout(TM->getSubtargetImpl()->getDataLayout());
>> +  RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
>>  }
>>
>>  MCJIT::~MCJIT() {
>> @@ -99,13 +101,13 @@ bool MCJIT::removeModule(Module *M) {
>>  }
>>
>>  void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
>> -  std::unique_ptr<ObjectImage> LoadedObject = Dyld.loadObject(std::move(Obj));
>> -  if (!LoadedObject || Dyld.hasError())
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
>> +  if (Dyld.hasError())
>>      report_fatal_error(Dyld.getErrorString());
>>
>> -  NotifyObjectEmitted(*LoadedObject);
>> +  NotifyObjectEmitted(*Obj, *L);
>>
>> -  LoadedObjects.push_back(std::move(LoadedObject));
>> +  LoadedObjects.push_back(std::move(Obj));
>>  }
>>
>>  void MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
>> @@ -125,7 +127,7 @@ void MCJIT::setObjectCache(ObjectCache*
>>    ObjCache = NewCache;
>>  }
>>
>> -std::unique_ptr<ObjectBufferStream> MCJIT::emitObject(Module *M) {
>> +std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
>>    MutexGuard locked(lock);
>>
>>    // This must be a module which has already been added but not loaded to this
>> @@ -138,30 +140,32 @@ std::unique_ptr<ObjectBufferStream> MCJI
>>    PM.add(new DataLayoutPass());
>>
>>    // The RuntimeDyld will take ownership of this shortly
>> -  std::unique_ptr<ObjectBufferStream> CompiledObject(new ObjectBufferStream());
>> +  SmallVector<char, 4096> ObjBufferSV;
>> +  raw_svector_ostream ObjStream(ObjBufferSV);
>>
>>    // Turn the machine code intermediate representation into bytes in memory
>>    // that may be executed.
>> -  if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(),
>> -                            !getVerifyModules())) {
>> +  if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !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
>> -  CompiledObject->flush();
>> +  ObjStream.flush();
>> +
>> +  std::unique_ptr<MemoryBuffer> CompiledObjBuffer(
>> +                                new ObjectMemoryBuffer(std::move(ObjBufferSV)));
>>
>>    // 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 = CompiledObject->getMemBuffer();
>> +    MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
>>      ObjCache->notifyObjectCompiled(M, MB);
>>    }
>>
>> -  return CompiledObject;
>> +  return CompiledObjBuffer;
>>  }
>>
>>  void MCJIT::generateCodeForModule(Module *M) {
>> @@ -176,14 +180,10 @@ void MCJIT::generateCodeForModule(Module
>>    if (OwnedModules.hasModuleBeenLoaded(M))
>>      return;
>>
>> -  std::unique_ptr<ObjectBuffer> ObjectToLoad;
>> +  std::unique_ptr<MemoryBuffer> ObjectToLoad;
>>    // Try to load the pre-compiled object from cache if possible
>> -  if (ObjCache) {
>> -    if (std::unique_ptr<MemoryBuffer> PreCompiledObject =
>> -            ObjCache->getObject(M))
>> -      ObjectToLoad =
>> -          llvm::make_unique<ObjectBuffer>(std::move(PreCompiledObject));
>> -  }
>> +  if (ObjCache)
>> +    ObjectToLoad = ObjCache->getObject(M);
>>
>>    // If the cache did not contain a suitable object, compile the object
>>    if (!ObjectToLoad) {
>> @@ -193,17 +193,18 @@ void MCJIT::generateCodeForModule(Module
>>
>>    // Load the object into the dynamic linker.
>>    // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
>> -  std::unique_ptr<ObjectImage> LoadedObject =
>> -      Dyld.loadObject(std::move(ObjectToLoad));
>> -  if (!LoadedObject)
>> -    report_fatal_error(Dyld.getErrorString());
>> +  ErrorOr<std::unique_ptr<object::ObjectFile>> LoadedObject =
>> +    object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
>> +    Dyld.loadObject(*LoadedObject.get());
>>
>> -  // FIXME: Make this optional, maybe even move it to a JIT event listener
>> -  LoadedObject->registerWithDebugger();
>> +  if (Dyld.hasError())
>> +    report_fatal_error(Dyld.getErrorString());
>>
>> -  NotifyObjectEmitted(*LoadedObject);
>> +  NotifyObjectEmitted(*LoadedObject.get(), *L);
>>
>> -  LoadedObjects.push_back(std::move(LoadedObject));
>> +  Buffers.push_back(std::move(ObjectToLoad));
>> +  LoadedObjects.push_back(std::move(*LoadedObject));
>>
>>    OwnedModules.markModuleAsLoaded(M);
>>  }
>> @@ -549,6 +550,7 @@ void MCJIT::RegisterJITEventListener(JIT
>>    MutexGuard locked(lock);
>>    EventListeners.push_back(L);
>>  }
>> +
>>  void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
>>    if (!L)
>>      return;
>> @@ -559,14 +561,17 @@ void MCJIT::UnregisterJITEventListener(J
>>      EventListeners.pop_back();
>>    }
>>  }
>> -void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {
>> +
>> +void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj,
>> +                                const RuntimeDyld::LoadedObjectInfo &L) {
>>    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);
>> +    EventListeners[I]->NotifyObjectEmitted(Obj, L);
>>    }
>>  }
>> -void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) {
>> +
>> +void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) {
>>    MutexGuard locked(lock);
>>    for (JITEventListener *L : EventListeners)
>>      L->NotifyFreeingObject(Obj);
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Wed Nov 26 00:53:26 2014
>> @@ -10,12 +10,12 @@
>>  #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 ObjectImage *Obj) override {
>> +                          const object::ObjectFile &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<ObjectImage>, 2> LoadedObjects;
>> +  SmallVector<std::unique_ptr<object::ObjectFile>, 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,10 +341,11 @@ 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<ObjectBufferStream> emitObject(Module *M);
>> +  std::unique_ptr<MemoryBuffer> emitObject(Module *M);
>>
>> -  void NotifyObjectEmitted(const ObjectImage& Obj);
>> -  void NotifyFreeingObject(const ObjectImage& Obj);
>> +  void NotifyObjectEmitted(const object::ObjectFile& Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L);
>> +  void NotifyFreeingObject(const object::ObjectFile& Obj);
>>
>>    uint64_t getExistingSymbolAddress(const std::string &Name);
>>    Module *findModuleForSymbol(const std::string &Name,
>>
>> Copied: llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h (from r222801, llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h)
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h?p2=llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h&p1=llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h&r1=222801&r2=222810&rev=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h Wed Nov 26 00:53:26 2014
>> @@ -1,4 +1,4 @@
>> -//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
>> +//===--- ObjectBuffer.h - Utility class to wrap object memory ---*- C++ -*-===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -21,54 +21,26 @@
>>
>>  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();
>> +class ObjectMemoryBuffer : public MemoryBuffer {
>>  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();
>> +  template <unsigned N>
>> +  ObjectMemoryBuffer(SmallVector<char, N> SV)
>> +    : SV(SV), BufferName("<in-memory object>") {
>> +    init(this->SV.begin(), this->SV.end(), false);
>>    }
>>
>> -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);
>> +  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; }
>>
>> -protected:
>> -  SmallVector<char, 4096> SV; // Working buffer into which we JIT.
>> -  raw_svector_ostream     OS; // streaming wrapper
>> +private:
>> +  SmallVector<char, 4096> SV;
>> +  std::string BufferName;
>>  };
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -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"
>> @@ -31,31 +31,34 @@
>>
>>  using namespace llvm;
>>  using namespace llvm::jitprofiling;
>> +using namespace llvm::object;
>>
>>  #define DEBUG_TYPE "oprofile-jit-event-listener"
>>
>>  namespace {
>>
>>  class OProfileJITEventListener : public JITEventListener {
>> -  OProfileWrapper& Wrapper;
>> +  std::unique_ptr<OProfileWrapper> Wrapper;
>>
>>    void initialize();
>> +  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
>>
>>  public:
>> -  OProfileJITEventListener(OProfileWrapper& LibraryWrapper)
>> -  : Wrapper(LibraryWrapper) {
>> +  OProfileJITEventListener(std::unique_ptr<OProfileWrapper> LibraryWrapper)
>> +    : Wrapper(std::move(LibraryWrapper)) {
>>      initialize();
>>    }
>>
>>    ~OProfileJITEventListener();
>>
>> -  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
>> +  void NotifyObjectEmitted(const ObjectFile &Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L) override;
>>
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj);
>> +  void NotifyFreeingObject(const ObjectFile &Obj) override;
>>  };
>>
>>  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 {
>> @@ -64,8 +67,8 @@ void OProfileJITEventListener::initializ
>>  }
>>
>>  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");
>> @@ -75,17 +78,22 @@ OProfileJITEventListener::~OProfileJITEv
>>    }
>>  }
>>
>> -void OProfileJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
>> -  if (!Wrapper.isAgentAvailable()) {
>> +void OProfileJITEventListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Obj,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +  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 (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
>> +  for (symbol_iterator I = DebugObj.symbol_begin(), E = DebugObj.symbol_end();
>>         I != E; ++I) {
>> -    object::SymbolRef::Type SymType;
>> +    SymbolRef::Type SymType;
>>      if (I->getType(SymType)) continue;
>> -    if (SymType == object::SymbolRef::ST_Function) {
>> +    if (SymType == SymbolRef::ST_Function) {
>>        StringRef  Name;
>>        uint64_t   Addr;
>>        uint64_t   Size;
>> @@ -93,7 +101,7 @@ void OProfileJITEventListener::NotifyObj
>>        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 ["
>> @@ -103,45 +111,48 @@ void OProfileJITEventListener::NotifyObj
>>        // TODO: support line number info (similar to IntelJITEventListener.cpp)
>>      }
>>    }
>> -}
>>
>> -void OProfileJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
>> -  if (!Wrapper.isAgentAvailable()) {
>> -    return;
>> -  }
>> +  DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
>> +}
>>
>> -  // 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;
>> +void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
>> +  if (Wrapper->isAgentAvailable()) {
>>
>> -      if (Wrapper.op_unload_native_code(Addr) == -1) {
>> -        DEBUG(dbgs()
>> -          << "Failed to tell OProfile about unload of native function at "
>> -          << (void*)Addr << "\n");
>> -        continue;
>> +    // 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;
>> +        }
>>        }
>>      }
>>    }
>> +
>> +  DebugObjects.erase(Obj.getData().data());
>>  }
>>
>>  }  // anonymous namespace.
>>
>>  namespace llvm {
>>  JITEventListener *JITEventListener::createOProfileJITEventListener() {
>> -  static std::unique_ptr<OProfileWrapper> JITProfilingWrapper(
>> -      new OProfileWrapper);
>> -  return new OProfileJITEventListener(*JITProfilingWrapper);
>> -}
>> -
>> -// for testing
>> -JITEventListener *JITEventListener::createOProfileJITEventListener(
>> -                                      OProfileWrapper* TestImpl) {
>> -  return new OProfileJITEventListener(*TestImpl);
>> +  return new OProfileJITEventListener(llvm::make_unique<OProfileWrapper>());
>>  }
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt Wed Nov 26 00:53:26 2014
>> @@ -1,5 +1,5 @@
>>  add_llvm_library(LLVMRuntimeDyld
>> -  GDBRegistrar.cpp
>> +  GDBRegistrationListener.cpp
>>    RuntimeDyld.cpp
>>    RuntimeDyldChecker.cpp
>>    RuntimeDyldELF.cpp
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (removed)
>> @@ -1,213 +0,0 @@
>> -//===-- 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
>>
>> Copied: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp (from r222764, llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp)
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp?p2=llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp&p1=llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp&r1=222764&r2=222810&rev=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -1,4 +1,4 @@
>> -//===-- GDBRegistrar.cpp - Registers objects with GDB ---------------------===//
>> +//===----- GDBRegistrationListener.cpp - Registers objects with GDB -------===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -7,8 +7,9 @@
>>  //
>>  //===----------------------------------------------------------------------===//
>>
>> -#include "JITRegistrar.h"
>>  #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"
>> @@ -16,6 +17,7 @@
>>  #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" {
>> @@ -60,37 +62,49 @@ extern "C" {
>>
>>  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*,
>> -                        std::pair<std::size_t, jit_code_entry*> >
>> +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 GDBJITRegistrar : public JITRegistrar {
>> +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.
>> -  GDBJITRegistrar() : ObjectBufferMap() {}
>> +  GDBJITRegistrationListener() : ObjectBufferMap() {}
>>
>>    /// Unregisters each object that was previously registered and releases all
>>    /// internal resources.
>> -  virtual ~GDBJITRegistrar();
>> +  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 registerObject(const ObjectBuffer &Object) override;
>> +  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.
>> -  bool deregisterObject(const ObjectBuffer &Object) override;
>> +  void NotifyFreeingObject(const ObjectFile &Object) override;
>>
>>  private:
>>    /// Deregister the debug info for the given object file from the debugger
>> @@ -119,10 +133,11 @@ void NotifyDebugger(jit_code_entry* JITC
>>    __jit_debug_register_code();
>>  }
>>
>> -GDBJITRegistrar::~GDBJITRegistrar() {
>> +GDBJITRegistrationListener::~GDBJITRegistrationListener() {
>>    // Free all registered object files.
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end();
>> +  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.
>> @@ -131,14 +146,19 @@ GDBJITRegistrar::~GDBJITRegistrar() {
>>    ObjectBufferMap.clear();
>>  }
>>
>> -void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) {
>> +void GDBJITRegistrationListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Object,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +
>> +  OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Object);
>> +  const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
>> +  size_t      Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
>>
>> -  const char *Buffer = Object.getBufferStart();
>> -  size_t      Size = Object.getBufferSize();
>> +  const char *Key = Object.getMemoryBufferRef().getBufferStart();
>>
>> -  assert(Buffer && "Attempt to register a null object with a debugger.");
>> +  assert(Key && "Attempt to register a null object with a debugger.");
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  assert(ObjectBufferMap.find(Buffer) == ObjectBufferMap.end() &&
>> +  assert(ObjectBufferMap.find(Key) == ObjectBufferMap.end() &&
>>           "Second attempt to perform debug registration.");
>>    jit_code_entry* JITCodeEntry = new jit_code_entry();
>>
>> @@ -149,28 +169,27 @@ void GDBJITRegistrar::registerObject(con
>>      JITCodeEntry->symfile_addr = Buffer;
>>      JITCodeEntry->symfile_size = Size;
>>
>> -    ObjectBufferMap[Buffer] = std::make_pair(Size, JITCodeEntry);
>> +    ObjectBufferMap[Key] = RegisteredObjectInfo(Size, JITCodeEntry,
>> +                                                std::move(DebugObj));
>
> This broke the build with MSVC -- it turns out that MSVC is attempting
> to copy the RegisteredObjectInfo object into the DenseMap, which
> triggers a use of the deleted unique_ptr::operator= (implicitly
> created for OwningBinary).
>
> http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/11753/steps/build_llvm/logs/stdio
>
> ~Aaron
>
>>      NotifyDebugger(JITCodeEntry);
>>    }
>>  }
>>
>> -bool GDBJITRegistrar::deregisterObject(const ObjectBuffer& Object) {
>> -  const char *Buffer = Object.getBufferStart();
>> +void GDBJITRegistrationListener::NotifyFreeingObject(const ObjectFile& Object) {
>> +  const char *Key = Object.getMemoryBufferRef().getBufferStart();
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer);
>> +  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Key);
>>
>>    if (I != ObjectBufferMap.end()) {
>>      deregisterObjectInternal(I);
>>      ObjectBufferMap.erase(I);
>> -    return true;
>>    }
>> -  return false;
>>  }
>>
>> -void GDBJITRegistrar::deregisterObjectInternal(
>> +void GDBJITRegistrationListener::deregisterObjectInternal(
>>      RegisteredObjectBufferMap::iterator I) {
>>
>> -  jit_code_entry*& JITCodeEntry = I->second.second;
>> +  jit_code_entry*& JITCodeEntry = I->second.Entry;
>>
>>    // Do the unregistration.
>>    {
>> @@ -200,14 +219,14 @@ void GDBJITRegistrar::deregisterObjectIn
>>    JITCodeEntry = nullptr;
>>  }
>>
>> -llvm::ManagedStatic<GDBJITRegistrar> TheRegistrar;
>> +llvm::ManagedStatic<GDBJITRegistrationListener> GDBRegListener;
>>
>>  } // end namespace
>>
>>  namespace llvm {
>>
>> -JITRegistrar& JITRegistrar::getGDBRegistrar() {
>> -  return *TheRegistrar;
>> +JITEventListener* JITEventListener::createGDBRegistrationListener() {
>> +  return &*GDBRegListener;
>>  }
>>
>>  } // namespace llvm
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h (removed)
>> @@ -1,44 +0,0 @@
>> -//===-- 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
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (removed)
>> @@ -1,86 +0,0 @@
>> -//===-- 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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Wed Nov 26 00:53:26 2014
>> @@ -12,8 +12,6 @@
>>  //===----------------------------------------------------------------------===//
>>
>>  #include "llvm/ExecutionEngine/RuntimeDyld.h"
>> -#include "JITRegistrar.h"
>> -#include "ObjectImageCommon.h"
>>  #include "RuntimeDyldCheckerImpl.h"
>>  #include "RuntimeDyldELF.h"
>>  #include "RuntimeDyldImpl.h"
>> @@ -30,10 +28,8 @@ using namespace llvm::object;
>>  // Empty out-of-line virtual destructor as the key function.
>>  RuntimeDyldImpl::~RuntimeDyldImpl() {}
>>
>> -// Pin the JITRegistrar's and ObjectImage*'s vtables to this file.
>> -void JITRegistrar::anchor() {}
>> -void ObjectImage::anchor() {}
>> -void ObjectImageCommon::anchor() {}
>> +// Pin LoadedObjectInfo's vtables to this file.
>> +void RuntimeDyld::LoadedObjectInfo::anchor() {}
>>
>>  namespace llvm {
>>
>> @@ -139,22 +135,23 @@ static std::error_code getOffset(const S
>>    return object_error::success;
>>  }
>>
>> -std::unique_ptr<ObjectImage>
>> -RuntimeDyldImpl::loadObject(std::unique_ptr<ObjectImage> Obj) {
>> +std::pair<unsigned, unsigned>
>> +RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
>>    MutexGuard locked(lock);
>>
>> -  if (!Obj)
>> -    return nullptr;
>> +  // Grab the first Section ID. We'll use this later to construct the underlying
>> +  // range for the returned LoadedObjectInfo.
>> +  unsigned SectionsAddedBeginIdx = Sections.size();
>>
>>    // Save information about our target
>> -  Arch = (Triple::ArchType)Obj->getArch();
>> -  IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian();
>> +  Arch = (Triple::ArchType)Obj.getArch();
>> +  IsTargetLittleEndian = Obj.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);
>>    }
>>
>> @@ -170,7 +167,7 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>    // Parse symbols
>>    DEBUG(dbgs() << "Parse symbols:\n");
>> -  for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E;
>> +  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
>>         ++I) {
>>      object::SymbolRef::Type SymType;
>>      StringRef Name;
>> @@ -196,15 +193,15 @@ RuntimeDyldImpl::loadObject(std::unique_
>>            SymType == object::SymbolRef::ST_Unknown) {
>>          uint64_t SectOffset;
>>          StringRef SectionData;
>> -        section_iterator SI = Obj->end_sections();
>> +        section_iterator SI = Obj.section_end();
>>          Check(getOffset(*I, SectOffset));
>>          Check(I->getSection(SI));
>> -        if (SI == Obj->end_sections())
>> +        if (SI == Obj.section_end())
>>            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);
>> @@ -216,11 +213,11 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>    // 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->begin_sections(), SE = Obj->end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      unsigned SectionID = 0;
>>      StubMap Stubs;
>> @@ -234,23 +231,25 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>      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->getImageName(), SectionID, Stubs);
>> +      Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
>>    }
>>
>>    // Give the subclasses a chance to tie-up any loose ends.
>> -  finalizeLoad(*Obj, LocalSections);
>> +  finalizeLoad(Obj, LocalSections);
>>
>> -  return Obj;
>> +  unsigned SectionsAddedEndIdx = Sections.size();
>> +
>> +  return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
>>  }
>>
>>  // A helper method for computeTotalAllocSize.
>> @@ -270,7 +269,7 @@ computeAllocationSizeForSections(std::ve
>>
>>  // Compute an upper bound of the memory size that is required to load all
>>  // sections
>> -void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
>> +void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
>>                                              uint64_t &CodeSize,
>>                                              uint64_t &DataSizeRO,
>>                                              uint64_t &DataSizeRW) {
>> @@ -282,7 +281,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>
>>    // Collect sizes of all sections to be loaded;
>>    // also determine the max alignment of all sections
>> -  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      const SectionRef &Section = *SI;
>>
>> @@ -328,7 +327,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>
>>    // Compute the size of all common symbols
>>    uint64_t CommonSize = 0;
>> -  for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
>> +  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
>>         ++I) {
>>      uint32_t Flags = I->getFlags();
>>      if (Flags & SymbolRef::SF_Common) {
>> @@ -353,7 +352,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>  }
>>
>>  // compute stub buffer size for the given section
>> -unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
>>                                                      const SectionRef &Section) {
>>    unsigned StubSize = getMaxStubSize();
>>    if (StubSize == 0) {
>> @@ -363,7 +362,7 @@ unsigned RuntimeDyldImpl::computeSection
>>    // necessary section allocation size in loadObject by walking all the sections
>>    // once.
>>    unsigned StubBufSize = 0;
>> -  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      section_iterator RelSecI = SI->getRelocatedSection();
>>      if (!(RelSecI == Section))
>> @@ -418,7 +417,7 @@ void RuntimeDyldImpl::writeBytesUnaligne
>>    }
>>  }
>>
>> -void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
>> +void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
>>                                          const CommonSymbolMap &CommonSymbols,
>>                                          uint64_t TotalSize,
>>                                          SymbolTableMap &SymbolTable) {
>> @@ -450,14 +449,13 @@ void RuntimeDyldImpl::emitCommonSymbols(
>>        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(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
>>                                        const SectionRef &Section, bool IsCode) {
>>
>>    StringRef data;
>> @@ -521,7 +519,6 @@ unsigned RuntimeDyldImpl::emitSection(Ob
>>                   << " 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
>> @@ -537,12 +534,12 @@ unsigned RuntimeDyldImpl::emitSection(Ob
>>    Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
>>
>>    if (Checker)
>> -    Checker->registerSection(Obj.getImageName(), SectionID);
>> +    Checker->registerSection(Obj.getFileName(), SectionID);
>>
>>    return SectionID;
>>  }
>>
>> -unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::findOrEmitSection(const ObjectFile &Obj,
>>                                              const SectionRef &Section,
>>                                              bool IsCode,
>>                                              ObjSectionToIDMap &LocalSections) {
>> @@ -739,6 +736,16 @@ void RuntimeDyldImpl::resolveExternalSym
>>
>>  //===----------------------------------------------------------------------===//
>>  // 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
>> @@ -772,78 +779,23 @@ createRuntimeDyldMachO(Triple::ArchType
>>    return Dyld;
>>  }
>>
>> -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 (InputObject->isMachO()) {
>> -    InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject)));
>> -    if (!Dyld)
>> -      Dyld = createRuntimeDyldMachO(
>> -          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)
>> +std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
>> +RuntimeDyld::loadObject(const ObjectFile &Obj) {
>> +  if (!Dyld) {
>> +    if (Obj.isELF())
>>        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)
>> +    else if (Obj.isMachO())
>>        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!");
>> +               static_cast<Triple::ArchType>(Obj.getArch()), MM,
>> +               ProcessAllSections, Checker);
>> +    else
>> +      report_fatal_error("Incompatible object format!");
>>    }
>>
>> -  if (!Dyld->isCompatibleFormat(InputBufferPtr))
>> +  if (!Dyld->isCompatibleFile(Obj))
>>      report_fatal_error("Incompatible object format!");
>>
>> -  return Dyld->loadObject(std::move(InputImage));
>> +  return Dyld->loadObject(Obj);
>>  }
>>
>>  void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Wed Nov 26 00:53:26 2014
>> @@ -12,27 +12,23 @@
>>  //===----------------------------------------------------------------------===//
>>
>>  #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/ExecutionEngine/ObjectBuffer.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>> +#include "llvm/MC/MCStreamer.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());
>> @@ -40,6 +36,8 @@ static inline std::error_code check(std:
>>    return Err;
>>  }
>>
>> +namespace {
>> +
>>  template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
>>    LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
>>
>> @@ -52,16 +50,12 @@ template <class ELFT> class DyldELFObjec
>>
>>    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 &Sym, uint64_t Addr);
>> +
>> +  void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr);
>>
>>    // Methods for type inquiry through isa, cast and dyn_cast
>>    static inline bool classof(const Binary *v) {
>> @@ -71,42 +65,10 @@ 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
>> @@ -118,14 +80,6 @@ DyldELFObject<ELFT>::DyldELFObject(Memor
>>  }
>>
>>  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) {
>>    DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
>> @@ -149,10 +103,89 @@ void DyldELFObject<ELFT>::updateSymbolAd
>>    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;
>> @@ -180,83 +213,14 @@ void RuntimeDyldELF::deregisterEHFrames(
>>    RegisteredEHFrameSections.clear();
>>  }
>>
>> -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));
>> +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);
>>  }
>>
>> -RuntimeDyldELF::~RuntimeDyldELF() {}
>> -
>>  void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
>>                                               uint64_t Offset, uint64_t Value,
>>                                               uint32_t Type, int64_t Addend,
>> @@ -615,7 +579,7 @@ void RuntimeDyldELF::resolveMIPSRelocati
>>  }
>>
>>  // Return the .TOC. section and offset.
>> -void RuntimeDyldELF::findPPC64TOCSection(ObjectImage &Obj,
>> +void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
>>                                           ObjSectionToIDMap &LocalSections,
>>                                           RelocationValueRef &Rel) {
>>    // Set a default SectionID in case we do not find a TOC section below.
>> @@ -628,7 +592,7 @@ void RuntimeDyldELF::findPPC64TOCSection
>>
>>    // 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.begin_sections(), se = Obj.end_sections();
>> +  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
>>         si != se; ++si) {
>>
>>      StringRef SectionName;
>> @@ -650,15 +614,15 @@ void RuntimeDyldELF::findPPC64TOCSection
>>
>>  // Returns the sections and offset associated with the ODP entry referenced
>>  // by Symbol.
>> -void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
>> +void RuntimeDyldELF::findOPDEntrySection(const ObjectFile &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.begin_sections(), se = Obj.end_sections();
>> +  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
>>         si != se; ++si) {
>>      section_iterator RelSecI = si->getRelocatedSection();
>> -    if (RelSecI == Obj.end_sections())
>> +    if (RelSecI == Obj.section_end())
>>        continue;
>>
>>      StringRef RelSectionName;
>> @@ -700,7 +664,7 @@ void RuntimeDyldELF::findOPDEntrySection
>>        if (Rel.Addend != (int64_t)TargetSymbolOffset)
>>          continue;
>>
>> -      section_iterator tsi(Obj.end_sections());
>> +      section_iterator tsi(Obj.section_end());
>>        check(TargetSymbol->getSection(tsi));
>>        bool IsCode = tsi->isText();
>>        Rel.SectionID = findOrEmitSection(Obj, (*tsi), IsCode, LocalSections);
>> @@ -935,7 +899,8 @@ void RuntimeDyldELF::resolveRelocation(c
>>  }
>>
>>  relocation_iterator RuntimeDyldELF::processRelocationRef(
>> -    unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
>> +    unsigned SectionID, relocation_iterator RelI,
>> +    const ObjectFile &Obj,
>>      ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
>>      StubMap &Stubs) {
>>    uint64_t RelType;
>> @@ -946,7 +911,7 @@ relocation_iterator RuntimeDyldELF::proc
>>
>>    // Obtain the symbol name which is referenced in the relocation
>>    StringRef TargetName;
>> -  if (Symbol != Obj.end_symbols())
>> +  if (Symbol != Obj.symbol_end())
>>      Symbol->getName(TargetName);
>>    DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
>>                 << " TargetName: " << TargetName << "\n");
>> @@ -954,7 +919,7 @@ relocation_iterator RuntimeDyldELF::proc
>>    // 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.end_symbols()) {
>> +  if (Symbol != Obj.symbol_end()) {
>>      lsi = Symbols.find(TargetName.data());
>>      Symbol->getType(SymType);
>>    }
>> @@ -965,7 +930,7 @@ relocation_iterator RuntimeDyldELF::proc
>>    } else {
>>      // Search for the symbol in the global symbol table
>>      SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end();
>> -    if (Symbol != Obj.end_symbols())
>> +    if (Symbol != Obj.symbol_end())
>>        gsi = GlobalSymbolTable.find(TargetName.data());
>>      if (gsi != GlobalSymbolTable.end()) {
>>        Value.SectionID = gsi->second.first;
>> @@ -977,9 +942,9 @@ relocation_iterator RuntimeDyldELF::proc
>>          // 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.end_sections());
>> +        section_iterator si(Obj.section_end());
>>          Symbol->getSection(si);
>> -        if (si == Obj.end_sections())
>> +        if (si == Obj.section_end())
>>            llvm_unreachable("Symbol section not found, bad object file format!");
>>          DEBUG(dbgs() << "\t\tThis is section symbol\n");
>>          bool isCode = si->isText();
>> @@ -1135,7 +1100,7 @@ relocation_iterator RuntimeDyldELF::proc
>>      if (RelType == ELF::R_PPC64_REL24) {
>>        // Determine ABI variant in use for this object.
>>        unsigned AbiVariant;
>> -      Obj.getObjectFile()->getPlatformFlags(AbiVariant);
>> +      Obj.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
>> @@ -1495,7 +1460,7 @@ uint64_t RuntimeDyldELF::findGOTEntry(ui
>>    return 0;
>>  }
>>
>> -void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg,
>> +void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
>>                                    ObjSectionToIDMap &SectionMap) {
>>    // If necessary, allocate the global offset table
>>    if (MemMgr) {
>> @@ -1533,15 +1498,8 @@ void RuntimeDyldELF::finalizeLoad(Object
>>    }
>>  }
>>
>> -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();
>> +bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const {
>> +  return Obj.isELF();
>>  }
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Wed Nov 26 00:53:26 2014
>> @@ -28,9 +28,11 @@ std::error_code Check(std::error_code Er
>>    }
>>    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);
>> @@ -81,9 +83,11 @@ class RuntimeDyldELF : public RuntimeDyl
>>        return 1;
>>    }
>>
>> -  void findPPC64TOCSection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
>> +  void findPPC64TOCSection(const ObjectFile &Obj,
>> +                           ObjSectionToIDMap &LocalSections,
>>                             RelocationValueRef &Rel);
>> -  void findOPDEntrySection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
>> +  void findOPDEntrySection(const ObjectFile &Obj,
>> +                           ObjSectionToIDMap &LocalSections,
>>                             RelocationValueRef &Rel);
>>
>>    uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
>> @@ -104,24 +108,23 @@ class RuntimeDyldELF : public RuntimeDyl
>>    SmallVector<SID, 2> RegisteredEHFrameSections;
>>
>>  public:
>> -  RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
>> +  RuntimeDyldELF(RTDyldMemoryManager *mm);
>> +  virtual ~RuntimeDyldELF();
>> +
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
>> +  loadObject(const object::ObjectFile &O) override;
>>
>>    void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
>>    relocation_iterator
>>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,
>> -                       ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
>> +                       const ObjectFile &Obj,
>> +                       ObjSectionToIDMap &ObjSectionToID,
>>                         const SymbolTableMap &Symbols, StubMap &Stubs) override;
>> -  bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
>> -  bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
>> +  bool isCompatibleFile(const object::ObjectFile &Obj) const override;
>>    void registerEHFrames() override;
>>    void deregisterEHFrames() override;
>> -  void finalizeLoad(ObjectImage &ObjImg,
>> +  void finalizeLoad(const ObjectFile &Obj,
>>                      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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Wed Nov 26 00:53:26 2014
>> @@ -18,7 +18,6 @@
>>  #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"
>> @@ -37,7 +36,6 @@ using namespace llvm::object;
>>
>>  namespace llvm {
>>
>> -class ObjectBuffer;
>>  class Twine;
>>
>>  /// SectionEntry - represents a section emitted into memory by the dynamic
>> @@ -159,6 +157,7 @@ public:
>>  };
>>
>>  class RuntimeDyldImpl {
>> +  friend class RuntimeDyld::LoadedObjectInfo;
>>    friend class RuntimeDyldCheckerImpl;
>>  private:
>>
>> @@ -296,14 +295,15 @@ 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(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols,
>> +  void emitCommonSymbols(const ObjectFile &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(ObjectImage &Obj, const SectionRef &Section,
>> +  unsigned emitSection(const ObjectFile &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(ObjectImage &Obj, const SectionRef &Section,
>> +  unsigned findOrEmitSection(const ObjectFile &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,
>> -                       ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
>> +                       const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID,
>>                         const SymbolTableMap &Symbols, StubMap &Stubs) = 0;
>>
>>    /// \brief Resolve relocations to external symbols.
>> @@ -351,13 +351,16 @@ protected:
>>
>>    // \brief Compute an upper bound of the memory that is required to load all
>>    // sections
>> -  void computeTotalAllocSize(ObjectImage &Obj, uint64_t &CodeSize,
>> +  void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize,
>>                               uint64_t &DataSizeRO, uint64_t &DataSizeRW);
>>
>>    // \brief Compute the stub buffer size required for a section
>> -  unsigned computeSectionStubBufSize(ObjectImage &Obj,
>> +  unsigned computeSectionStubBufSize(const ObjectFile &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) {
>> @@ -373,8 +376,8 @@ public:
>>      this->Checker = Checker;
>>    }
>>
>> -  std::unique_ptr<ObjectImage>
>> -  loadObject(std::unique_ptr<ObjectImage> InputObject);
>> +  virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
>> +  loadObject(const object::ObjectFile &Obj) = 0;
>>
>>    uint8_t* getSymbolAddress(StringRef Name) const {
>>      // FIXME: Just look up as a function for now. Overly simple of course.
>> @@ -411,14 +414,14 @@ public:
>>    // Get the error message.
>>    StringRef getErrorString() { return ErrorStr; }
>>
>> -  virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0;
>> -  virtual bool isCompatibleFile(const ObjectFile *Obj) const = 0;
>> +  virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0;
>>
>>    virtual void registerEHFrames();
>>
>>    virtual void deregisterEHFrames();
>>
>> -  virtual void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) {}
>> +  virtual void finalizeLoad(const ObjectFile &ObjImg,
>> +                            ObjSectionToIDMap &SectionMap) {}
>>  };
>>
>>  } // end namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp Wed Nov 26 00:53:26 2014
>> @@ -25,6 +25,22 @@ 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 {
>> @@ -35,12 +51,12 @@ int64_t RuntimeDyldMachO::memcpyAddend(c
>>  }
>>
>>  RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
>> -    ObjectImage &ObjImg, const relocation_iterator &RI,
>> +    const ObjectFile &BaseTObj, const relocation_iterator &RI,
>>      const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID,
>>      const SymbolTableMap &Symbols) {
>>
>>    const MachOObjectFile &Obj =
>> -      static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
>> +      static_cast<const MachOObjectFile &>(BaseTObj);
>>    MachO::any_relocation_info RelInfo =
>>        Obj.getRelocation(RI->getRawDataRefImpl());
>>    RelocationValueRef Value;
>> @@ -67,7 +83,7 @@ RelocationValueRef RuntimeDyldMachO::get
>>    } else {
>>      SectionRef Sec = Obj.getRelocationSection(RelInfo);
>>      bool IsCode = Sec.isText();
>> -    Value.SectionID = findOrEmitSection(ObjImg, Sec, IsCode, ObjSectionToID);
>> +    Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID);
>>      uint64_t Addr = Sec.getAddress();
>>      Value.Offset = RE.Addend - Addr;
>>    }
>> @@ -76,11 +92,11 @@ RelocationValueRef RuntimeDyldMachO::get
>>  }
>>
>>  void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value,
>> -                                            ObjectImage &ObjImg,
>> +                                            const ObjectFile &BaseTObj,
>>                                              const relocation_iterator &RI,
>>                                              unsigned OffsetToNextPC) {
>>    const MachOObjectFile &Obj =
>> -      static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
>> +      static_cast<const MachOObjectFile &>(BaseTObj);
>>    MachO::any_relocation_info RelInfo =
>>        Obj.getRelocation(RI->getRawDataRefImpl());
>>
>> @@ -125,7 +141,7 @@ RuntimeDyldMachO::getSectionByAddress(co
>>
>>  // Populate __pointers section.
>>  void RuntimeDyldMachO::populateIndirectSymbolPointersSection(
>> -                                                    MachOObjectFile &Obj,
>> +                                                    const MachOObjectFile &Obj,
>>                                                      const SectionRef &PTSection,
>>                                                      unsigned PTSectionID) {
>>    assert(!Obj.is64Bit() &&
>> @@ -163,28 +179,12 @@ void RuntimeDyldMachO::populateIndirectS
>>    }
>>  }
>>
>> -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();
>> +bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile &Obj) const {
>> +  return Obj.isMachO();
>>  }
>>
>>  template <typename Impl>
>> -void RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(ObjectImage &ObjImg,
>> +void RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &ObjImg,
>>                                                    ObjSectionToIDMap &SectionMap) {
>>    unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
>>    unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
>> @@ -284,7 +284,7 @@ void RuntimeDyldMachOCRTPBase<Impl>::reg
>>  }
>>
>>  std::unique_ptr<RuntimeDyldMachO>
>> -llvm::RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
>> +RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
>>    switch (Arch) {
>>    default:
>>      llvm_unreachable("Unsupported target for RuntimeDyldMachO.");
>> @@ -296,4 +296,12 @@ llvm::RuntimeDyldMachO::create(Triple::A
>>    }
>>  }
>>
>> +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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h Wed Nov 26 00:53:26 2014
>> @@ -14,7 +14,6 @@
>>  #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"
>> @@ -61,10 +60,11 @@ 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, ObjectImage &ObjImg,
>> +  RelocationEntry getRelocationEntry(unsigned SectionID,
>> +                                     const ObjectFile &BaseTObj,
>>                                       const relocation_iterator &RI) const {
>>      const MachOObjectFile &Obj =
>> -      static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
>> +      static_cast<const MachOObjectFile &>(BaseTObj);
>>      MachO::any_relocation_info RelInfo =
>>        Obj.getRelocation(RI->getRawDataRefImpl());
>>
>> @@ -87,14 +87,15 @@ 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(ObjectImage &ObjImg,
>> +  RelocationValueRef getRelocationValueRef(const ObjectFile &BaseTObj,
>>                                             const relocation_iterator &RI,
>>                                             const RelocationEntry &RE,
>>                                             ObjSectionToIDMap &ObjSectionToID,
>>                                             const SymbolTableMap &Symbols);
>>
>>    /// Make the RelocationValueRef addend PC-relative.
>> -  void makeValueAddendPCRel(RelocationValueRef &Value, ObjectImage &ObjImg,
>> +  void makeValueAddendPCRel(RelocationValueRef &Value,
>> +                            const ObjectFile &BaseTObj,
>>                              const relocation_iterator &RI,
>>                              unsigned OffsetToNextPC);
>>
>> @@ -107,31 +108,22 @@ protected:
>>
>>
>>    // Populate __pointers section.
>> -  void populateIndirectSymbolPointersSection(MachOObjectFile &Obj,
>> +  void populateIndirectSymbolPointersSection(const 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);
>> +
>>    SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
>>
>> -  bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
>> -  bool isCompatibleFile(const object::ObjectFile *Obj) const override;
>> +  bool isCompatibleFile(const object::ObjectFile &Obj) const override;
>>  };
>>
>>  /// RuntimeDyldMachOTarget - Templated base class for generic MachO linker
>> @@ -153,7 +145,7 @@ private:
>>  public:
>>    RuntimeDyldMachOCRTPBase(RTDyldMemoryManager *mm) : RuntimeDyldMachO(mm) {}
>>
>> -  void finalizeLoad(ObjectImage &ObjImg,
>> +  void finalizeLoad(const ObjectFile &Obj,
>>                      ObjSectionToIDMap &SectionMap) override;
>>    void registerEHFrames() override;
>>  };
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h Wed Nov 26 00:53:26 2014
>> @@ -243,10 +243,11 @@ public:
>>
>>    relocation_iterator
>>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,
>> -                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
>> +                       const ObjectFile &BaseObjT,
>> +                       ObjSectionToIDMap &ObjSectionToID,
>>                         const SymbolTableMap &Symbols, StubMap &Stubs) override {
>>      const MachOObjectFile &Obj =
>> -        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
>> +      static_cast<const MachOObjectFile &>(BaseObjT);
>>      MachO::any_relocation_info RelInfo =
>>          Obj.getRelocation(RelI->getRawDataRefImpl());
>>
>> @@ -268,10 +269,10 @@ public:
>>        RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl());
>>      }
>>
>> -    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
>> +    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
>>      RE.Addend = decodeAddend(RE);
>>      RelocationValueRef Value(
>> -        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
>> +        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols));
>>
>>      assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\
>>        "ARM64_RELOC_ADDEND and embedded addend in the instruction.");
>> @@ -282,7 +283,7 @@ public:
>>
>>      bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
>>      if (!IsExtern && RE.IsPCRel)
>> -      makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size);
>> +      makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size);
>>
>>      RE.Addend = Value.Offset;
>>
>> @@ -359,7 +360,7 @@ public:
>>      }
>>    }
>>
>> -  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
>> +  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
>>                         const SectionRef &Section) {}
>>
>>  private:
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h Wed Nov 26 00:53:26 2014
>> @@ -49,29 +49,30 @@ public:
>>
>>    relocation_iterator
>>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,
>> -                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
>> +                       const ObjectFile &BaseObjT,
>> +                       ObjSectionToIDMap &ObjSectionToID,
>>                         const SymbolTableMap &Symbols, StubMap &Stubs) override {
>>      const MachOObjectFile &Obj =
>> -        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
>> +        static_cast<const MachOObjectFile &>(BaseObjT);
>>      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, ObjImg,
>> +        return processHALFSECTDIFFRelocation(SectionID, RelI, Obj,
>>                                               ObjSectionToID);
>>        else
>>          return ++++RelI;
>>      }
>>
>> -    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
>> +    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
>>      RE.Addend = decodeAddend(RE);
>>      RelocationValueRef Value(
>> -        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
>> +        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols));
>>
>>      if (RE.IsPCRel)
>> -      makeValueAddendPCRel(Value, ObjImg, RelI, 8);
>> +      makeValueAddendPCRel(Value, Obj, RelI, 8);
>>
>>      if ((RE.RelType & 0xf) == MachO::ARM_RELOC_BR24)
>>        processBranchRelocation(RE, Value, Stubs);
>> @@ -154,15 +155,14 @@ public:
>>      }
>>    }
>>
>> -  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
>> +  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
>>                         const SectionRef &Section) {
>>      StringRef Name;
>>      Section.getName(Name);
>>
>>      if (Name == "__nl_symbol_ptr")
>> -      populateIndirectSymbolPointersSection(
>> -                                 cast<MachOObjectFile>(*ObjImg.getObjectFile()),
>> -                                 Section, SectionID);
>> +      populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj),
>> +                                            Section, SectionID);
>>    }
>>
>>  private:
>> @@ -199,25 +199,25 @@ private:
>>
>>    relocation_iterator
>>    processHALFSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,
>> -                                ObjectImage &Obj,
>> +                                const ObjectFile &BaseTObj,
>>                                  ObjSectionToIDMap &ObjSectionToID) {
>> -    const MachOObjectFile *MachO =
>> -        static_cast<const MachOObjectFile *>(Obj.getObjectFile());
>> +    const MachOObjectFile &MachO =
>> +        static_cast<const MachOObjectFile&>(BaseTObj);
>>      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(Obj, SectionA, IsCode, ObjSectionToID);
>> +        findOrEmitSection(MachO, 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(Obj, SectionB, IsCode, ObjSectionToID);
>> +        findOrEmitSection(MachO, 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);
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h Wed Nov 26 00:53:26 2014
>> @@ -31,10 +31,11 @@ public:
>>
>>    relocation_iterator
>>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,
>> -                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
>> +                       const ObjectFile &BaseObjT,
>> +                       ObjSectionToIDMap &ObjSectionToID,
>>                         const SymbolTableMap &Symbols, StubMap &Stubs) override {
>>      const MachOObjectFile &Obj =
>> -        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
>> +        static_cast<const MachOObjectFile &>(BaseObjT);
>>      MachO::any_relocation_info RelInfo =
>>          Obj.getRelocation(RelI->getRawDataRefImpl());
>>      uint32_t RelType = Obj.getAnyRelocationType(RelInfo);
>> @@ -42,18 +43,18 @@ public:
>>      if (Obj.isRelocationScattered(RelInfo)) {
>>        if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
>>            RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
>> -        return processSECTDIFFRelocation(SectionID, RelI, ObjImg,
>> +        return processSECTDIFFRelocation(SectionID, RelI, Obj,
>>                                           ObjSectionToID);
>>        else if (RelType == MachO::GENERIC_RELOC_VANILLA)
>> -        return processI386ScatteredVANILLA(SectionID, RelI, ObjImg,
>> +        return processI386ScatteredVANILLA(SectionID, RelI, Obj,
>>                                             ObjSectionToID);
>>        llvm_unreachable("Unhandled scattered relocation.");
>>      }
>>
>> -    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
>> +    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
>>      RE.Addend = memcpyAddend(RE);
>>      RelocationValueRef Value(
>> -        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
>> +        getRelocationValueRef(Obj, 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.
>> @@ -66,7 +67,7 @@ public:
>>      //   Value.Addend += RelocAddr + 4;
>>      // }
>>      if (RE.IsPCRel)
>> -      makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size);
>> +      makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size);
>>
>>      RE.Addend = Value.Offset;
>>
>> @@ -110,34 +111,32 @@ public:
>>      }
>>    }
>>
>> -  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
>> +  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
>>                         const SectionRef &Section) {
>>      StringRef Name;
>>      Section.getName(Name);
>>
>>      if (Name == "__jump_table")
>> -      populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()), Section,
>> -                        SectionID);
>> +      populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID);
>>      else if (Name == "__pointers")
>> -      populateIndirectSymbolPointersSection(
>> -                                 cast<MachOObjectFile>(*ObjImg.getObjectFile()),
>> -                                 Section, SectionID);
>> +      populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj),
>> +                                            Section, SectionID);
>>    }
>>
>>  private:
>>    relocation_iterator
>>    processSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,
>> -                            ObjectImage &Obj,
>> +                            const ObjectFile &BaseObjT,
>>                              ObjSectionToIDMap &ObjSectionToID) {
>> -    const MachOObjectFile *MachO =
>> -        static_cast<const MachOObjectFile *>(Obj.getObjectFile());
>> +    const MachOObjectFile &Obj =
>> +        static_cast<const MachOObjectFile&>(BaseObjT);
>>      MachO::any_relocation_info RE =
>> -        MachO->getRelocation(RelI->getRawDataRefImpl());
>> +        Obj.getRelocation(RelI->getRawDataRefImpl());
>>
>>      SectionEntry &Section = Sections[SectionID];
>> -    uint32_t RelocType = MachO->getAnyRelocationType(RE);
>> -    bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
>> -    unsigned Size = MachO->getAnyRelocationLength(RE);
>> +    uint32_t RelocType = Obj.getAnyRelocationType(RE);
>> +    bool IsPCRel = Obj.getAnyRelocationPCRel(RE);
>> +    unsigned Size = Obj.getAnyRelocationLength(RE);
>>      uint64_t Offset;
>>      RelI->getOffset(Offset);
>>      uint8_t *LocalAddress = Section.Address + Offset;
>> @@ -146,11 +145,11 @@ private:
>>
>>      ++RelI;
>>      MachO::any_relocation_info RE2 =
>> -        MachO->getRelocation(RelI->getRawDataRefImpl());
>> +        Obj.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");
>> +    uint32_t AddrA = Obj.getScatteredRelocationValue(RE);
>> +    section_iterator SAI = getSectionByAddress(Obj, AddrA);
>> +    assert(SAI != Obj.section_end() && "Can't find section for address A");
>>      uint64_t SectionABase = SAI->getAddress();
>>      uint64_t SectionAOffset = AddrA - SectionABase;
>>      SectionRef SectionA = *SAI;
>> @@ -158,9 +157,9 @@ private:
>>      uint32_t SectionAID =
>>          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 = Obj.getScatteredRelocationValue(RE2);
>> +    section_iterator SBI = getSectionByAddress(Obj, AddrB);
>> +    assert(SBI != Obj.section_end() && "Can't find section for address B");
>>      uint64_t SectionBBase = SBI->getAddress();
>>      uint64_t SectionBOffset = AddrB - SectionBBase;
>>      SectionRef SectionB = *SBI;
>> @@ -186,26 +185,27 @@ private:
>>    }
>>
>>    relocation_iterator processI386ScatteredVANILLA(
>> -      unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
>> +      unsigned SectionID, relocation_iterator RelI,
>> +      const ObjectFile &BaseObjT,
>>        RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID) {
>> -    const MachOObjectFile *MachO =
>> -        static_cast<const MachOObjectFile *>(Obj.getObjectFile());
>> +    const MachOObjectFile &Obj =
>> +        static_cast<const MachOObjectFile&>(BaseObjT);
>>      MachO::any_relocation_info RE =
>> -        MachO->getRelocation(RelI->getRawDataRefImpl());
>> +        Obj.getRelocation(RelI->getRawDataRefImpl());
>>
>>      SectionEntry &Section = Sections[SectionID];
>> -    uint32_t RelocType = MachO->getAnyRelocationType(RE);
>> -    bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
>> -    unsigned Size = MachO->getAnyRelocationLength(RE);
>> +    uint32_t RelocType = Obj.getAnyRelocationType(RE);
>> +    bool IsPCRel = Obj.getAnyRelocationPCRel(RE);
>> +    unsigned Size = Obj.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 = MachO->getScatteredRelocationValue(RE);
>> -    section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr);
>> -    assert(TargetSI != MachO->section_end() && "Can't find section for symbol");
>> +    unsigned SymbolBaseAddr = Obj.getScatteredRelocationValue(RE);
>> +    section_iterator TargetSI = getSectionByAddress(Obj, SymbolBaseAddr);
>> +    assert(TargetSI != Obj.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(MachOObjectFile &Obj, const SectionRef &JTSection,
>> +  void populateJumpTable(const MachOObjectFile &Obj, const SectionRef &JTSection,
>>                           unsigned JTSectionID) {
>>      assert(!Obj.is64Bit() &&
>>             "__jump_table section not supported in 64-bit MachO.");
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h Wed Nov 26 00:53:26 2014
>> @@ -31,24 +31,25 @@ public:
>>
>>    relocation_iterator
>>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,
>> -                       ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
>> +                       const ObjectFile &BaseObjT,
>> +                       ObjSectionToIDMap &ObjSectionToID,
>>                         const SymbolTableMap &Symbols, StubMap &Stubs) override {
>>      const MachOObjectFile &Obj =
>> -        static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
>> +      static_cast<const MachOObjectFile &>(BaseObjT);
>>      MachO::any_relocation_info RelInfo =
>>          Obj.getRelocation(RelI->getRawDataRefImpl());
>>
>>      assert(!Obj.isRelocationScattered(RelInfo) &&
>>             "Scattered relocations not supported on X86_64");
>>
>> -    RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI));
>> +    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
>>      RE.Addend = memcpyAddend(RE);
>>      RelocationValueRef Value(
>> -        getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
>> +        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols));
>>
>>      bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
>>      if (!IsExtern && RE.IsPCRel)
>> -      makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size);
>> +      makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size);
>>
>>      if (RE.RelType == MachO::X86_64_RELOC_GOT ||
>>          RE.RelType == MachO::X86_64_RELOC_GOT_LOAD)
>> @@ -97,7 +98,7 @@ public:
>>      }
>>    }
>>
>> -  void finalizeSection(ObjectImage &ObjImg, unsigned SectionID,
>> +  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
>>                         const SectionRef &Section) {}
>>
>>  private:
>>
>> Modified: llvm/trunk/tools/lli/RemoteMemoryManager.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/lli/RemoteMemoryManager.cpp (original)
>> +++ llvm/trunk/tools/lli/RemoteMemoryManager.cpp Wed Nov 26 00:53:26 2014
>> @@ -14,7 +14,6 @@
>>
>>  #include "RemoteMemoryManager.h"
>>  #include "llvm/ExecutionEngine/ExecutionEngine.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>>  #include "llvm/Support/Debug.h"
>>  #include "llvm/Support/Format.h"
>>
>> @@ -78,7 +77,7 @@ sys::MemoryBlock RemoteMemoryManager::al
>>  }
>>
>>  void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE,
>> -                                                const ObjectImage *Obj) {
>> +                                             const object::ObjectFile &Obj) {
>>    // The client should have called setRemoteTarget() before triggering any
>>    // code generation.
>>    assert(Target);
>>
>> Modified: llvm/trunk/tools/lli/RemoteMemoryManager.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/lli/RemoteMemoryManager.h (original)
>> +++ llvm/trunk/tools/lli/RemoteMemoryManager.h Wed Nov 26 00:53:26 2014
>> @@ -80,7 +80,8 @@ public:
>>    // symbols from Modules it contains.
>>    uint64_t getSymbolAddress(const std::string &Name) override { return 0; }
>>
>> -  void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj) override;
>> +  void notifyObjectLoaded(ExecutionEngine *EE,
>> +                          const object::ObjectFile &Obj) override;
>>
>>    bool finalizeMemory(std::string *ErrMsg) override;
>>
>>
>> Modified: llvm/trunk/tools/llvm-jitlistener/llvm-jitlistener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-jitlistener/llvm-jitlistener.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/llvm-jitlistener/llvm-jitlistener.cpp (original)
>> +++ llvm/trunk/tools/llvm-jitlistener/llvm-jitlistener.cpp Wed Nov 26 00:53:26 2014
>> @@ -19,10 +19,10 @@
>>  #include "llvm/ExecutionEngine/JITEventListener.h"
>>  #include "llvm/ExecutionEngine/SectionMemoryManager.h"
>>  #include "llvm/ExecutionEngine/MCJIT.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>>  #include "llvm/IR/Module.h"
>>  #include "llvm/IRReader/IRReader.h"
>>  #include "llvm/Support/CommandLine.h"
>> +#include "llvm/Support/Debug.h"
>>  #include "llvm/Support/Host.h"
>>  #include "llvm/Support/ManagedStatic.h"
>>  #include "llvm/Support/MemoryBuffer.h"
>>
>> Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
>> +++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Wed Nov 26 00:53:26 2014
>> @@ -13,8 +13,6 @@
>>
>>  #include "llvm/ADT/StringMap.h"
>>  #include "llvm/DebugInfo/DIContext.h"
>> -#include "llvm/ExecutionEngine/ObjectBuffer.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>>  #include "llvm/ExecutionEngine/RuntimeDyld.h"
>>  #include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
>>  #include "llvm/MC/MCAsmInfo.h"
>> @@ -207,23 +205,32 @@ static int printLineInfoForInput() {
>>      if (std::error_code EC = InputBuffer.getError())
>>        return Error("unable to read input: '" + EC.message() + "'");
>>
>> -    std::unique_ptr<ObjectImage> LoadedObject;
>> +    ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
>> +      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
>> +
>> +    if (std::error_code EC = MaybeObj.getError())
>> +      return Error("unable to create object file: '" + EC.message() + "'");
>> +
>> +    ObjectFile &Obj = **MaybeObj;
>> +
>>      // Load the object file
>> -    LoadedObject = Dyld.loadObject(
>> -        llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
>> -    if (!LoadedObject) {
>> +    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo =
>> +      Dyld.loadObject(Obj);
>> +
>> +    if (Dyld.hasError())
>>        return Error(Dyld.getErrorString());
>> -    }
>>
>>      // Resolve all the relocations we can.
>>      Dyld.resolveRelocations();
>>
>> +    OwningBinary<ObjectFile> DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
>> +
>>      std::unique_ptr<DIContext> Context(
>> -        DIContext::getDWARFContext(*LoadedObject->getObjectFile()));
>> +      DIContext::getDWARFContext(*DebugObj.getBinary()));
>>
>>      // Use symbol info to iterate functions in the object.
>> -    for (object::symbol_iterator I = LoadedObject->begin_symbols(),
>> -                                 E = LoadedObject->end_symbols();
>> +    for (object::symbol_iterator I = DebugObj.getBinary()->symbol_begin(),
>> +                                 E = DebugObj.getBinary()->symbol_end();
>>           I != E; ++I) {
>>        object::SymbolRef::Type SymType;
>>        if (I->getType(SymType)) continue;
>> @@ -268,11 +275,17 @@ static int executeInput() {
>>          MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
>>      if (std::error_code EC = InputBuffer.getError())
>>        return Error("unable to read input: '" + EC.message() + "'");
>> -    std::unique_ptr<ObjectImage> LoadedObject;
>> +    ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
>> +      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
>> +
>> +    if (std::error_code EC = MaybeObj.getError())
>> +      return Error("unable to create object file: '" + EC.message() + "'");
>> +
>> +    ObjectFile &Obj = **MaybeObj;
>> +
>>      // Load the object file
>> -    LoadedObject = Dyld.loadObject(
>> -        llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
>> -    if (!LoadedObject) {
>> +    Dyld.loadObject(Obj);
>> +    if (Dyld.hasError()) {
>>        return Error(Dyld.getErrorString());
>>      }
>>    }
>> @@ -512,14 +525,21 @@ 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() + "'");
>>
>> -    std::unique_ptr<ObjectImage> LoadedObject;
>> +    ErrorOr<std::unique_ptr<ObjectFile>> MaybeObj(
>> +      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
>> +
>> +    if (std::error_code EC = MaybeObj.getError())
>> +      return Error("unable to create object file: '" + EC.message() + "'");
>> +
>> +    ObjectFile &Obj = **MaybeObj;
>> +
>>      // Load the object file
>> -    LoadedObject = Dyld.loadObject(
>> -        llvm::make_unique<ObjectBuffer>(std::move(*InputBuffer)));
>> -    if (!LoadedObject) {
>> +    Dyld.loadObject(Obj);
>> +    if (Dyld.hasError()) {
>>        return Error(Dyld.getErrorString());
>>      }
>>    }
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> On Wed, Nov 26, 2014 at 1:53 AM, Lang Hames <lhames at gmail.com> wrote:
>> Author: lhames
>> Date: Wed Nov 26 00:53:26 2014
>> New Revision: 222810
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=222810&view=rev
>> Log:
>> [MCJIT] Clean up RuntimeDyld's quirky object-ownership/modification scheme.
>>
>> Previously, when loading an object file, RuntimeDyld (1) took ownership of the
>> ObjectFile instance (and associated MemoryBuffer), (2) potentially modified the
>> object in-place, and (3) returned an ObjectImage that managed ownership of the
>> now-modified object and provided some convenience methods. This scheme accreted
>> over several years as features were tacked on to RuntimeDyld, and was both
>> unintuitive and unsafe (See e.g. http://llvm.org/PR20722).
>>
>> This patch fixes the issue by removing all ownership and in-place modification
>> of object files from RuntimeDyld. Existing behavior, including debugger
>> registration, is preserved.
>>
>> Noteworthy changes include:
>>
>> (1) ObjectFile instances are now passed to RuntimeDyld by const-ref.
>> (2) The ObjectImage and ObjectBuffer classes have been removed entirely, they
>>     existed to model ownership within RuntimeDyld, and so are no longer needed.
>> (3) RuntimeDyld::loadObject now returns an instance of a new class,
>>     RuntimeDyld::LoadedObjectInfo, which can be used to construct a modified
>>     object suitable for registration with the debugger, following the existing
>>     debugger registration scheme.
>> (4) The JITRegistrar class has been removed, and the GDBRegistrar class has been
>>     re-written as a JITEventListener.
>>
>> This should fix http://llvm.org/PR20722 .
>>
>>
>> Added:
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h
>>       - copied, changed from r222801, llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp
>>       - copied, changed from r222764, llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>> Removed:
>>     llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>>     llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
>>     llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
>> Modified:
>>     llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
>>     llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
>>     llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
>>     llvm/trunk/lib/ExecutionEngine/CMakeLists.txt
>>     llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
>>     llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>>     llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
>>     llvm/trunk/tools/lli/RemoteMemoryManager.cpp
>>     llvm/trunk/tools/lli/RemoteMemoryManager.h
>>     llvm/trunk/tools/llvm-jitlistener/llvm-jitlistener.cpp
>>     llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h Wed Nov 26 00:53:26 2014
>> @@ -15,6 +15,7 @@
>>  #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"
>> @@ -25,7 +26,10 @@ class Function;
>>  class MachineFunction;
>>  class OProfileWrapper;
>>  class IntelJITEventsWrapper;
>> -class ObjectImage;
>> +
>> +namespace object {
>> +  class ObjectFile;
>> +}
>>
>>  /// JITEvent_EmittedFunctionDetails - Helper struct for containing information
>>  /// about a generated machine code function.
>> @@ -57,7 +61,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
>> @@ -67,11 +71,15 @@ 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 ObjectImage &Obj) {}
>> +  virtual void NotifyObjectEmitted(const object::ObjectFile &Obj,
>> +                                   const RuntimeDyld::LoadedObjectInfo &L) {}
>>
>>    /// NotifyFreeingObject - Called just before the memory associated with
>>    /// a previously emitted object is released.
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
>> +  virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {}
>> +
>> +  // Get a pointe to the GDB debugger registration listener.
>> +  static JITEventListener *createGDBRegistrationListener();
>>
>>  #if LLVM_USE_INTEL_JITEVENTS
>>    // Construct an IntelJITEventListener
>> @@ -105,7 +113,8 @@ public:
>>      return nullptr;
>>    }
>>  #endif // USE_OPROFILE
>> -
>> +private:
>> +  virtual void anchor();
>>  };
>>
>>  } // end namespace llvm.
>>
>> Removed: llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (removed)
>> @@ -1,76 +0,0 @@
>> -//===---- 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
>>
>> Removed: llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h (removed)
>> @@ -1,76 +0,0 @@
>> -//===---- 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
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h Wed Nov 26 00:53:26 2014
>> @@ -22,7 +22,10 @@
>>  namespace llvm {
>>
>>  class ExecutionEngine;
>> -class ObjectImage;
>> +
>> +  namespace object {
>> +    class ObjectFile;
>> +  }
>>
>>  // RuntimeDyld clients often want to handle the memory management of
>>  // what gets placed where. For JIT clients, this is the subset of
>> @@ -109,7 +112,7 @@ public:
>>    /// address space can use this call to remap the section addresses for the
>>    /// newly loaded object.
>>    virtual void notifyObjectLoaded(ExecutionEngine *EE,
>> -                                  const ObjectImage *) {}
>> +                                  const object::ObjectFile &) {}
>>
>>    /// This method is called when object loading is complete and section page
>>    /// permissions can be applied.  It is up to the memory manager implementation
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Wed Nov 26 00:53:26 2014
>> @@ -15,19 +15,19 @@
>>  #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,22 +46,35 @@ 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();
>>
>> -  /// 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);
>> +  /// Add the referenced object file to the list of objects to be loaded and
>> +  /// relocated.
>> +  std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O);
>>
>>    /// 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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/CMakeLists.txt?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/ExecutionEngine/CMakeLists.txt Wed Nov 26 00:53:26 2014
>> @@ -3,7 +3,6 @@
>>  add_llvm_library(LLVMExecutionEngine
>>    ExecutionEngine.cpp
>>    ExecutionEngineBindings.cpp
>> -  JITEventListener.cpp
>>    RTDyldMemoryManager.cpp
>>    TargetSelect.cpp
>>    )
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Wed Nov 26 00:53:26 2014
>> @@ -16,8 +16,7 @@
>>  #include "llvm/ADT/SmallString.h"
>>  #include "llvm/ADT/Statistic.h"
>>  #include "llvm/ExecutionEngine/GenericValue.h"
>> -#include "llvm/ExecutionEngine/ObjectBuffer.h"
>> -#include "llvm/ExecutionEngine/ObjectCache.h"
>> +#include "llvm/ExecutionEngine/JITEventListener.h"
>>  #include "llvm/IR/Constants.h"
>>  #include "llvm/IR/DataLayout.h"
>>  #include "llvm/IR/DerivedTypes.h"
>> @@ -43,17 +42,15 @@ 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) {
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -21,7 +21,6 @@
>>  #include "llvm/ADT/DenseMap.h"
>>  #include "llvm/CodeGen/MachineFunction.h"
>>  #include "llvm/DebugInfo/DIContext.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>>  #include "llvm/Object/ObjectFile.h"
>>  #include "llvm/Support/Debug.h"
>>  #include "llvm/Support/raw_ostream.h"
>> @@ -32,6 +31,7 @@
>>
>>  using namespace llvm;
>>  using namespace llvm::jitprofiling;
>> +using namespace llvm::object;
>>
>>  #define DEBUG_TYPE "amplifier-jit-event-listener"
>>
>> @@ -48,6 +48,7 @@ class IntelJITEventListener : public JIT
>>    typedef DenseMap<const void *, MethodAddressVector>  ObjectMap;
>>
>>    ObjectMap  LoadedObjectMap;
>> +  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
>>
>>  public:
>>    IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
>> @@ -57,9 +58,10 @@ public:
>>    ~IntelJITEventListener() {
>>    }
>>
>> -  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
>> +  void NotifyObjectEmitted(const ObjectFile &Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L) override;
>>
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj);
>> +  void NotifyFreeingObject(const ObjectFile &Obj) override;
>>  };
>>
>>  static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress,
>> @@ -95,23 +97,29 @@ static iJIT_Method_Load FunctionDescToIn
>>    return Result;
>>  }
>>
>> -void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
>> +void IntelJITEventListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Obj,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +
>> +  OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
>> +  const ObjectFile &DebugObj = *DebugObjOwner.getBinary();
>> +
>>    // Get the address of the object image for use as a unique identifier
>> -  const void* ObjData = Obj.getData().data();
>> -  DIContext* Context = DIContext::getDWARFContext(*Obj.getObjectFile());
>> +  const void* ObjData = DebugObj.getData().data();
>> +  DIContext* Context = DIContext::getDWARFContext(DebugObj);
>>    MethodAddressVector Functions;
>>
>>    // Use symbol info to iterate functions in the object.
>> -  for (object::symbol_iterator I = Obj.begin_symbols(),
>> -                               E = Obj.end_symbols();
>> +  for (symbol_iterator I = DebugObj.symbol_begin(),
>> +                       E = DebugObj.symbol_end();
>>                          I != E;
>>                          ++I) {
>>      std::vector<LineNumberInfo> LineInfo;
>>      std::string SourceFileName;
>>
>> -    object::SymbolRef::Type SymType;
>> +    SymbolRef::Type SymType;
>>      if (I->getType(SymType)) continue;
>> -    if (SymType == object::SymbolRef::ST_Function) {
>> +    if (SymType == SymbolRef::ST_Function) {
>>        StringRef  Name;
>>        uint64_t   Addr;
>>        uint64_t   Size;
>> @@ -162,11 +170,18 @@ void IntelJITEventListener::NotifyObject
>>    // registered function addresses for each loaded object.  We will
>>    // use the MethodIDs map to get the registered ID for each function.
>>    LoadedObjectMap[ObjData] = Functions;
>> +  DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
>>  }
>>
>> -void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
>> +void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
>> +  // This object may not have been registered with the listener. If it wasn't,
>> +  // bail out.
>> +  if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end())
>> +    return;
>> +
>>    // Get the address of the object image for use as a unique identifier
>> -  const void* ObjData = Obj.getData().data();
>> +  const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary();
>> +  const void* ObjData = DebugObj.getData().data();
>>
>>    // Get the object's function list from LoadedObjectMap
>>    ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
>> @@ -190,6 +205,7 @@ void IntelJITEventListener::NotifyFreein
>>
>>    // Erase the object from LoadedObjectMap
>>    LoadedObjectMap.erase(OI);
>> +  DebugObjects.erase(Obj.getData().data());
>>  }
>>
>>  }  // anonymous namespace.
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp (removed)
>> @@ -1,15 +0,0 @@
>> -//===-- 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() {}
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Wed Nov 26 00:53:26 2014
>> @@ -11,8 +11,6 @@
>>  #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"
>> @@ -21,6 +19,7 @@
>>  #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"
>> @@ -31,6 +30,8 @@
>>
>>  using namespace llvm;
>>
>> +void ObjectCache::anchor() {}
>> +
>>  namespace {
>>
>>  static struct RegisterJIT {
>> @@ -74,6 +75,7 @@ MCJIT::MCJIT(std::unique_ptr<Module> M,
>>
>>    OwnedModules.addModule(std::move(First));
>>    setDataLayout(TM->getSubtargetImpl()->getDataLayout());
>> +  RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
>>  }
>>
>>  MCJIT::~MCJIT() {
>> @@ -99,13 +101,13 @@ bool MCJIT::removeModule(Module *M) {
>>  }
>>
>>  void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
>> -  std::unique_ptr<ObjectImage> LoadedObject = Dyld.loadObject(std::move(Obj));
>> -  if (!LoadedObject || Dyld.hasError())
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
>> +  if (Dyld.hasError())
>>      report_fatal_error(Dyld.getErrorString());
>>
>> -  NotifyObjectEmitted(*LoadedObject);
>> +  NotifyObjectEmitted(*Obj, *L);
>>
>> -  LoadedObjects.push_back(std::move(LoadedObject));
>> +  LoadedObjects.push_back(std::move(Obj));
>>  }
>>
>>  void MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
>> @@ -125,7 +127,7 @@ void MCJIT::setObjectCache(ObjectCache*
>>    ObjCache = NewCache;
>>  }
>>
>> -std::unique_ptr<ObjectBufferStream> MCJIT::emitObject(Module *M) {
>> +std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
>>    MutexGuard locked(lock);
>>
>>    // This must be a module which has already been added but not loaded to this
>> @@ -138,30 +140,32 @@ std::unique_ptr<ObjectBufferStream> MCJI
>>    PM.add(new DataLayoutPass());
>>
>>    // The RuntimeDyld will take ownership of this shortly
>> -  std::unique_ptr<ObjectBufferStream> CompiledObject(new ObjectBufferStream());
>> +  SmallVector<char, 4096> ObjBufferSV;
>> +  raw_svector_ostream ObjStream(ObjBufferSV);
>>
>>    // Turn the machine code intermediate representation into bytes in memory
>>    // that may be executed.
>> -  if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(),
>> -                            !getVerifyModules())) {
>> +  if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !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
>> -  CompiledObject->flush();
>> +  ObjStream.flush();
>> +
>> +  std::unique_ptr<MemoryBuffer> CompiledObjBuffer(
>> +                                new ObjectMemoryBuffer(std::move(ObjBufferSV)));
>>
>>    // 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 = CompiledObject->getMemBuffer();
>> +    MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
>>      ObjCache->notifyObjectCompiled(M, MB);
>>    }
>>
>> -  return CompiledObject;
>> +  return CompiledObjBuffer;
>>  }
>>
>>  void MCJIT::generateCodeForModule(Module *M) {
>> @@ -176,14 +180,10 @@ void MCJIT::generateCodeForModule(Module
>>    if (OwnedModules.hasModuleBeenLoaded(M))
>>      return;
>>
>> -  std::unique_ptr<ObjectBuffer> ObjectToLoad;
>> +  std::unique_ptr<MemoryBuffer> ObjectToLoad;
>>    // Try to load the pre-compiled object from cache if possible
>> -  if (ObjCache) {
>> -    if (std::unique_ptr<MemoryBuffer> PreCompiledObject =
>> -            ObjCache->getObject(M))
>> -      ObjectToLoad =
>> -          llvm::make_unique<ObjectBuffer>(std::move(PreCompiledObject));
>> -  }
>> +  if (ObjCache)
>> +    ObjectToLoad = ObjCache->getObject(M);
>>
>>    // If the cache did not contain a suitable object, compile the object
>>    if (!ObjectToLoad) {
>> @@ -193,17 +193,18 @@ void MCJIT::generateCodeForModule(Module
>>
>>    // Load the object into the dynamic linker.
>>    // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
>> -  std::unique_ptr<ObjectImage> LoadedObject =
>> -      Dyld.loadObject(std::move(ObjectToLoad));
>> -  if (!LoadedObject)
>> -    report_fatal_error(Dyld.getErrorString());
>> +  ErrorOr<std::unique_ptr<object::ObjectFile>> LoadedObject =
>> +    object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
>> +    Dyld.loadObject(*LoadedObject.get());
>>
>> -  // FIXME: Make this optional, maybe even move it to a JIT event listener
>> -  LoadedObject->registerWithDebugger();
>> +  if (Dyld.hasError())
>> +    report_fatal_error(Dyld.getErrorString());
>>
>> -  NotifyObjectEmitted(*LoadedObject);
>> +  NotifyObjectEmitted(*LoadedObject.get(), *L);
>>
>> -  LoadedObjects.push_back(std::move(LoadedObject));
>> +  Buffers.push_back(std::move(ObjectToLoad));
>> +  LoadedObjects.push_back(std::move(*LoadedObject));
>>
>>    OwnedModules.markModuleAsLoaded(M);
>>  }
>> @@ -549,6 +550,7 @@ void MCJIT::RegisterJITEventListener(JIT
>>    MutexGuard locked(lock);
>>    EventListeners.push_back(L);
>>  }
>> +
>>  void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
>>    if (!L)
>>      return;
>> @@ -559,14 +561,17 @@ void MCJIT::UnregisterJITEventListener(J
>>      EventListeners.pop_back();
>>    }
>>  }
>> -void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {
>> +
>> +void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj,
>> +                                const RuntimeDyld::LoadedObjectInfo &L) {
>>    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);
>> +    EventListeners[I]->NotifyObjectEmitted(Obj, L);
>>    }
>>  }
>> -void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) {
>> +
>> +void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) {
>>    MutexGuard locked(lock);
>>    for (JITEventListener *L : EventListeners)
>>      L->NotifyFreeingObject(Obj);
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Wed Nov 26 00:53:26 2014
>> @@ -10,12 +10,12 @@
>>  #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 ObjectImage *Obj) override {
>> +                          const object::ObjectFile &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<ObjectImage>, 2> LoadedObjects;
>> +  SmallVector<std::unique_ptr<object::ObjectFile>, 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,10 +341,11 @@ 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<ObjectBufferStream> emitObject(Module *M);
>> +  std::unique_ptr<MemoryBuffer> emitObject(Module *M);
>>
>> -  void NotifyObjectEmitted(const ObjectImage& Obj);
>> -  void NotifyFreeingObject(const ObjectImage& Obj);
>> +  void NotifyObjectEmitted(const object::ObjectFile& Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L);
>> +  void NotifyFreeingObject(const object::ObjectFile& Obj);
>>
>>    uint64_t getExistingSymbolAddress(const std::string &Name);
>>    Module *findModuleForSymbol(const std::string &Name,
>>
>> Copied: llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h (from r222801, llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h)
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h?p2=llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h&p1=llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h&r1=222801&r2=222810&rev=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h Wed Nov 26 00:53:26 2014
>> @@ -1,4 +1,4 @@
>> -//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
>> +//===--- ObjectBuffer.h - Utility class to wrap object memory ---*- C++ -*-===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -21,54 +21,26 @@
>>
>>  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();
>> +class ObjectMemoryBuffer : public MemoryBuffer {
>>  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();
>> +  template <unsigned N>
>> +  ObjectMemoryBuffer(SmallVector<char, N> SV)
>> +    : SV(SV), BufferName("<in-memory object>") {
>> +    init(this->SV.begin(), this->SV.end(), false);
>>    }
>>
>> -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);
>> +  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; }
>>
>> -protected:
>> -  SmallVector<char, 4096> SV; // Working buffer into which we JIT.
>> -  raw_svector_ostream     OS; // streaming wrapper
>> +private:
>> +  SmallVector<char, 4096> SV;
>> +  std::string BufferName;
>>  };
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -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"
>> @@ -31,31 +31,34 @@
>>
>>  using namespace llvm;
>>  using namespace llvm::jitprofiling;
>> +using namespace llvm::object;
>>
>>  #define DEBUG_TYPE "oprofile-jit-event-listener"
>>
>>  namespace {
>>
>>  class OProfileJITEventListener : public JITEventListener {
>> -  OProfileWrapper& Wrapper;
>> +  std::unique_ptr<OProfileWrapper> Wrapper;
>>
>>    void initialize();
>> +  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
>>
>>  public:
>> -  OProfileJITEventListener(OProfileWrapper& LibraryWrapper)
>> -  : Wrapper(LibraryWrapper) {
>> +  OProfileJITEventListener(std::unique_ptr<OProfileWrapper> LibraryWrapper)
>> +    : Wrapper(std::move(LibraryWrapper)) {
>>      initialize();
>>    }
>>
>>    ~OProfileJITEventListener();
>>
>> -  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
>> +  void NotifyObjectEmitted(const ObjectFile &Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L) override;
>>
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj);
>> +  void NotifyFreeingObject(const ObjectFile &Obj) override;
>>  };
>>
>>  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 {
>> @@ -64,8 +67,8 @@ void OProfileJITEventListener::initializ
>>  }
>>
>>  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");
>> @@ -75,17 +78,22 @@ OProfileJITEventListener::~OProfileJITEv
>>    }
>>  }
>>
>> -void OProfileJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
>> -  if (!Wrapper.isAgentAvailable()) {
>> +void OProfileJITEventListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Obj,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +  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 (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
>> +  for (symbol_iterator I = DebugObj.symbol_begin(), E = DebugObj.symbol_end();
>>         I != E; ++I) {
>> -    object::SymbolRef::Type SymType;
>> +    SymbolRef::Type SymType;
>>      if (I->getType(SymType)) continue;
>> -    if (SymType == object::SymbolRef::ST_Function) {
>> +    if (SymType == SymbolRef::ST_Function) {
>>        StringRef  Name;
>>        uint64_t   Addr;
>>        uint64_t   Size;
>> @@ -93,7 +101,7 @@ void OProfileJITEventListener::NotifyObj
>>        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 ["
>> @@ -103,45 +111,48 @@ void OProfileJITEventListener::NotifyObj
>>        // TODO: support line number info (similar to IntelJITEventListener.cpp)
>>      }
>>    }
>> -}
>>
>> -void OProfileJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
>> -  if (!Wrapper.isAgentAvailable()) {
>> -    return;
>> -  }
>> +  DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
>> +}
>>
>> -  // 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;
>> +void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
>> +  if (Wrapper->isAgentAvailable()) {
>>
>> -      if (Wrapper.op_unload_native_code(Addr) == -1) {
>> -        DEBUG(dbgs()
>> -          << "Failed to tell OProfile about unload of native function at "
>> -          << (void*)Addr << "\n");
>> -        continue;
>> +    // 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;
>> +        }
>>        }
>>      }
>>    }
>> +
>> +  DebugObjects.erase(Obj.getData().data());
>>  }
>>
>>  }  // anonymous namespace.
>>
>>  namespace llvm {
>>  JITEventListener *JITEventListener::createOProfileJITEventListener() {
>> -  static std::unique_ptr<OProfileWrapper> JITProfilingWrapper(
>> -      new OProfileWrapper);
>> -  return new OProfileJITEventListener(*JITProfilingWrapper);
>> -}
>> -
>> -// for testing
>> -JITEventListener *JITEventListener::createOProfileJITEventListener(
>> -                                      OProfileWrapper* TestImpl) {
>> -  return new OProfileJITEventListener(*TestImpl);
>> +  return new OProfileJITEventListener(llvm::make_unique<OProfileWrapper>());
>>  }
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt Wed Nov 26 00:53:26 2014
>> @@ -1,5 +1,5 @@
>>  add_llvm_library(LLVMRuntimeDyld
>> -  GDBRegistrar.cpp
>> +  GDBRegistrationListener.cpp
>>    RuntimeDyld.cpp
>>    RuntimeDyldChecker.cpp
>>    RuntimeDyldELF.cpp
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (removed)
>> @@ -1,213 +0,0 @@
>> -//===-- 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
>>
>> Copied: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp (from r222764, llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp)
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp?p2=llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp&p1=llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp&r1=222764&r2=222810&rev=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -1,4 +1,4 @@
>> -//===-- GDBRegistrar.cpp - Registers objects with GDB ---------------------===//
>> +//===----- GDBRegistrationListener.cpp - Registers objects with GDB -------===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -7,8 +7,9 @@
>>  //
>>  //===----------------------------------------------------------------------===//
>>
>> -#include "JITRegistrar.h"
>>  #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"
>> @@ -16,6 +17,7 @@
>>  #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" {
>> @@ -60,37 +62,49 @@ extern "C" {
>>
>>  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*,
>> -                        std::pair<std::size_t, jit_code_entry*> >
>> +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 GDBJITRegistrar : public JITRegistrar {
>> +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.
>> -  GDBJITRegistrar() : ObjectBufferMap() {}
>> +  GDBJITRegistrationListener() : ObjectBufferMap() {}
>>
>>    /// Unregisters each object that was previously registered and releases all
>>    /// internal resources.
>> -  virtual ~GDBJITRegistrar();
>> +  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 registerObject(const ObjectBuffer &Object) override;
>> +  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.
>> -  bool deregisterObject(const ObjectBuffer &Object) override;
>> +  void NotifyFreeingObject(const ObjectFile &Object) override;
>>
>>  private:
>>    /// Deregister the debug info for the given object file from the debugger
>> @@ -119,10 +133,11 @@ void NotifyDebugger(jit_code_entry* JITC
>>    __jit_debug_register_code();
>>  }
>>
>> -GDBJITRegistrar::~GDBJITRegistrar() {
>> +GDBJITRegistrationListener::~GDBJITRegistrationListener() {
>>    // Free all registered object files.
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end();
>> +  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.
>> @@ -131,14 +146,19 @@ GDBJITRegistrar::~GDBJITRegistrar() {
>>    ObjectBufferMap.clear();
>>  }
>>
>> -void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) {
>> +void GDBJITRegistrationListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Object,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +
>> +  OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Object);
>> +  const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
>> +  size_t      Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
>>
>> -  const char *Buffer = Object.getBufferStart();
>> -  size_t      Size = Object.getBufferSize();
>> +  const char *Key = Object.getMemoryBufferRef().getBufferStart();
>>
>> -  assert(Buffer && "Attempt to register a null object with a debugger.");
>> +  assert(Key && "Attempt to register a null object with a debugger.");
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  assert(ObjectBufferMap.find(Buffer) == ObjectBufferMap.end() &&
>> +  assert(ObjectBufferMap.find(Key) == ObjectBufferMap.end() &&
>>           "Second attempt to perform debug registration.");
>>    jit_code_entry* JITCodeEntry = new jit_code_entry();
>>
>> @@ -149,28 +169,27 @@ void GDBJITRegistrar::registerObject(con
>>      JITCodeEntry->symfile_addr = Buffer;
>>      JITCodeEntry->symfile_size = Size;
>>
>> -    ObjectBufferMap[Buffer] = std::make_pair(Size, JITCodeEntry);
>> +    ObjectBufferMap[Key] = RegisteredObjectInfo(Size, JITCodeEntry,
>> +                                                std::move(DebugObj));
>>      NotifyDebugger(JITCodeEntry);
>>    }
>>  }
>>
>> -bool GDBJITRegistrar::deregisterObject(const ObjectBuffer& Object) {
>> -  const char *Buffer = Object.getBufferStart();
>> +void GDBJITRegistrationListener::NotifyFreeingObject(const ObjectFile& Object) {
>> +  const char *Key = Object.getMemoryBufferRef().getBufferStart();
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer);
>> +  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Key);
>>
>>    if (I != ObjectBufferMap.end()) {
>>      deregisterObjectInternal(I);
>>      ObjectBufferMap.erase(I);
>> -    return true;
>>    }
>> -  return false;
>>  }
>>
>> -void GDBJITRegistrar::deregisterObjectInternal(
>> +void GDBJITRegistrationListener::deregisterObjectInternal(
>>      RegisteredObjectBufferMap::iterator I) {
>>
>> -  jit_code_entry*& JITCodeEntry = I->second.second;
>> +  jit_code_entry*& JITCodeEntry = I->second.Entry;
>>
>>    // Do the unregistration.
>>    {
>> @@ -200,14 +219,14 @@ void GDBJITRegistrar::deregisterObjectIn
>>    JITCodeEntry = nullptr;
>>  }
>>
>> -llvm::ManagedStatic<GDBJITRegistrar> TheRegistrar;
>> +llvm::ManagedStatic<GDBJITRegistrationListener> GDBRegListener;
>>
>>  } // end namespace
>>
>>  namespace llvm {
>>
>> -JITRegistrar& JITRegistrar::getGDBRegistrar() {
>> -  return *TheRegistrar;
>> +JITEventListener* JITEventListener::createGDBRegistrationListener() {
>> +  return &*GDBRegListener;
>>  }
>>
>>  } // namespace llvm
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h (removed)
>> @@ -1,44 +0,0 @@
>> -//===-- 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
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (removed)
>> @@ -1,86 +0,0 @@
>> -//===-- 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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Wed Nov 26 00:53:26 2014
>> @@ -12,8 +12,6 @@
>>  //===----------------------------------------------------------------------===//
>>
>>  #include "llvm/ExecutionEngine/RuntimeDyld.h"
>> -#include "JITRegistrar.h"
>> -#include "ObjectImageCommon.h"
>>  #include "RuntimeDyldCheckerImpl.h"
>>  #include "RuntimeDyldELF.h"
>>  #include "RuntimeDyldImpl.h"
>> @@ -30,10 +28,8 @@ using namespace llvm::object;
>>  // Empty out-of-line virtual destructor as the key function.
>>  RuntimeDyldImpl::~RuntimeDyldImpl() {}
>>
>> -// Pin the JITRegistrar's and ObjectImage*'s vtables to this file.
>> -void JITRegistrar::anchor() {}
>> -void ObjectImage::anchor() {}
>> -void ObjectImageCommon::anchor() {}
>> +// Pin LoadedObjectInfo's vtables to this file.
>> +void RuntimeDyld::LoadedObjectInfo::anchor() {}
>>
>>  namespace llvm {
>>
>> @@ -139,22 +135,23 @@ static std::error_code getOffset(const S
>>    return object_error::success;
>>  }
>>
>> -std::unique_ptr<ObjectImage>
>> -RuntimeDyldImpl::loadObject(std::unique_ptr<ObjectImage> Obj) {
>> +std::pair<unsigned, unsigned>
>> +RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
>>    MutexGuard locked(lock);
>>
>> -  if (!Obj)
>> -    return nullptr;
>> +  // Grab the first Section ID. We'll use this later to construct the underlying
>> +  // range for the returned LoadedObjectInfo.
>> +  unsigned SectionsAddedBeginIdx = Sections.size();
>>
>>    // Save information about our target
>> -  Arch = (Triple::ArchType)Obj->getArch();
>> -  IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian();
>> +  Arch = (Triple::ArchType)Obj.getArch();
>> +  IsTargetLittleEndian = Obj.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);
>>    }
>>
>> @@ -170,7 +167,7 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>    // Parse symbols
>>    DEBUG(dbgs() << "Parse symbols:\n");
>> -  for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E;
>> +  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
>>         ++I) {
>>      object::SymbolRef::Type SymType;
>>      StringRef Name;
>> @@ -196,15 +193,15 @@ RuntimeDyldImpl::loadObject(std::unique_
>>            SymType == object::SymbolRef::ST_Unknown) {
>>          uint64_t SectOffset;
>>          StringRef SectionData;
>> -        section_iterator SI = Obj->end_sections();
>> +        section_iterator SI = Obj.section_end();
>>          Check(getOffset(*I, SectOffset));
>>          Check(I->getSection(SI));
>> -        if (SI == Obj->end_sections())
>> +        if (SI == Obj.section_end())
>>            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);
>> @@ -216,11 +213,11 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>    // 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->begin_sections(), SE = Obj->end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      unsigned SectionID = 0;
>>      StubMap Stubs;
>> @@ -234,23 +231,25 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>      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->getImageName(), SectionID, Stubs);
>> +      Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
>>    }
>>
>>    // Give the subclasses a chance to tie-up any loose ends.
>> -  finalizeLoad(*Obj, LocalSections);
>> +  finalizeLoad(Obj, LocalSections);
>>
>> -  return Obj;
>> +  unsigned SectionsAddedEndIdx = Sections.size();
>> +
>> +  return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
>>  }
>>
>>  // A helper method for computeTotalAllocSize.
>> @@ -270,7 +269,7 @@ computeAllocationSizeForSections(std::ve
>>
>>  // Compute an upper bound of the memory size that is required to load all
>>  // sections
>> -void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
>> +void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
>>                                              uint64_t &CodeSize,
>>                                              uint64_t &DataSizeRO,
>>                                              uint64_t &DataSizeRW) {
>> @@ -282,7 +281,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>
>>    // Collect sizes of all sections to be loaded;
>>    // also determine the max alignment of all sections
>> -  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      const SectionRef &Section = *SI;
>>
>> @@ -328,7 +327,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>
>>    // Compute the size of all common symbols
>>    uint64_t CommonSize = 0;
>> -  for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
>> +  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
>>         ++I) {
>>      uint32_t Flags = I->getFlags();
>>      if (Flags & SymbolRef::SF_Common) {
>> @@ -353,7 +352,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>  }
>>
>>  // compute stub buffer size for the given section
>> -unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
>>                                                      const SectionRef &Section) {
>>    unsigned StubSize = getMaxStubSize();
>>    if (StubSize == 0) {
>> @@ -363,7 +362,7 @@ unsigned RuntimeDyldImpl::computeSection
>>    // necessary section allocation size in loadObject by walking all the sections
>>    // once.
>>    unsigned StubBufSize = 0;
>> -  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      section_iterator RelSecI = SI->getRelocatedSection();
>>      if (!(RelSecI == Section))
>> @@ -418,7 +417,7 @@ void RuntimeDyldImpl::writeBytesUnaligne
>>    }
>>  }
>>
>> -void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
>> +void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
>>                                          const CommonSymbolMap &CommonSymbols,
>>                                          uint64_t TotalSize,
>>                                          SymbolTableMap &SymbolTable) {
>> @@ -450,14 +449,13 @@ void RuntimeDyldImpl::emitCommonSymbols(
>>        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(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
>>                                        const SectionRef &Section, bool IsCode) {
>>
>>    StringRef data;
>> @@ -521,7 +519,6 @@ unsigned RuntimeDyldImpl::emitSection(Ob
>>                   << " 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
>> @@ -537,12 +534,12 @@ unsigned RuntimeDyldImpl::emitSection(Ob
>>    Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
>>
>>    if (Checker)
>> -    Checker->registerSection(Obj.getImageName(), SectionID);
>> +    Checker->registerSection(Obj.getFileName(), SectionID);
>>
>>    return SectionID;
>>  }
>>
>> -unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::findOrEmitSection(const ObjectFile &Obj,
>>                                              const SectionRef &Section,
>>                                              bool IsCode,
>>                                              ObjSectionToIDMap &LocalSections) {
>> @@ -739,6 +736,16 @@ void RuntimeDyldImpl::resolveExternalSym
>>
>>  //===----------------------------------------------------------------------===//
>>  // 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
>> @@ -772,78 +779,23 @@ createRuntimeDyldMachO(Triple::ArchType
>>    return Dyld;
>>  }
>>
>> -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 (InputObject->isMachO()) {
>> -    InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject)));
>> -    if (!Dyld)
>> -      Dyld = createRuntimeDyldMachO(
>> -          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)
>> +std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
>> +RuntimeDyld::loadObject(const ObjectFile &Obj) {
>> +  if (!Dyld) {
>> +    if (Obj.isELF())
>>        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)
>> +    else if (Obj.isMachO())
>>        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!");
>> +               static_cast<Triple::ArchType>(Obj.getArch()), MM,
>> +               ProcessAllSections, Checker);
>> +    else
>> +      report_fatal_error("Incompatible object format!");
>>    }
>>
>> -  if (!Dyld->isCompatibleFormat(InputBufferPtr))
>> +  if (!Dyld->isCompatibleFile(Obj))
>>      report_fatal_error("Incompatible object format!");
>>
>> -  return Dyld->loadObject(std::move(InputImage));
>> +  return Dyld->loadObject(Obj);
>>  }
>>
>>  void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Wed Nov 26 00:53:26 2014
>> @@ -12,27 +12,23 @@
>>  //===----------------------------------------------------------------------===//
>>
>>  #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/ExecutionEngine/ObjectBuffer.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>> +#include "llvm/MC/MCStreamer.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());
>> @@ -40,6 +36,8 @@ static inline std::error_code check(std:
>>    return Err;
>>  }
>>
>> +namespace {
>> +
>>  template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
>>    LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
>>
>> @@ -52,16 +50,12 @@ template <class ELFT> class DyldELFObjec
>>
>>    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 &Sym, uint64_t Addr);
>> +
>> +  void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr);
>>
>>    // Methods for type inquiry through isa, cast and dyn_cast
>>    static inline bool classof(const Binary *v) {
>> @@ -71,42 +65,10 @@ 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
>> @@ -118,14 +80,6 @@ DyldELFObject<ELFT>::DyldELFObject(Memor
>>  }
>>
>>  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) {
>>    DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
>> @@ -149,10 +103,89 @@ void DyldELFObject<ELFT>::updateSymbolAd
>>    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;
>> @@ -180,83 +213,14 @@ void RuntimeDyldELF::deregisterEHFrames(
>>    RegisteredEHFrameSections.clear();
>>  }
>>
>> -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));
>> +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);
>>  }
>>
>> -RuntimeDyldELF::~RuntimeDyldELF() {}
>> -
>>  void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
>>                                               uint64_t Offset, uint64_t Value,
>>                                               uint32_t Type, int64_t Addend,
>> @@ -615,7 +579,7 @@ void RuntimeDyldELF::resolveMIPSRelocati
>>  }
>>
>>  // Return the .TOC. section and offset.
>> -void RuntimeDyldELF::findPPC64TOCSection(ObjectImage &Obj,
>> +void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
>>                                           ObjSectionToIDMap &LocalSections,
>>                                           RelocationValueRef &Rel) {
>>    // Set a default SectionID in case we do not find a TOC section below.
>> @@ -628,7 +592,7 @@ void RuntimeDyldELF::findPPC64TOCSection
>>
>>    // 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.begin_sections(), se = Obj.end_sections();
>> +  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
>>         si != se; ++si) {
>>
>>      StringRef SectionName;
>> @@ -650,15 +614,15 @@ void RuntimeDyldELF::findPPC64TOCSection
>>
>>  // Returns the sections and offset associated with the ODP entry referenced
>>  // by Symbol.
>> -void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
>> +void RuntimeDyldELF::findOPDEntrySection(const ObjectFile &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.begin_sections(), se = Obj.end_sections();
>> +  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
>>         si != se; ++si) {
>>      section_iterator RelSecI = si->getRelocatedSection();
>> -    if (RelSecI == Obj.end_sections())
>> +    if (RelSecI == Obj.section_end())
>>        continue;
>>
>>      StringRef RelSectionName;
>> @@ -700,7 +664,7 @@ void RuntimeDyldELF::findOPDEntrySection
>>        if (Rel.Addend != (int64_t)TargetSymbolOffset)
>>          continue;
>>
>> -      section_iterator tsi(Obj.end_sections());
>> +      section_iterator tsi(Obj.section_end());
>>        check(TargetSymbol->getSection(tsi));
>>        bool IsCode = tsi->isText();
>>        Rel.SectionID = findOrEmitSection(Obj, (*tsi), IsCode, LocalSections);
>> @@ -935,7 +899,8 @@ void RuntimeDyldELF::resolveRelocation(c
>>  }
>>
>>  relocation_iterator RuntimeDyldELF::processRelocationRef(
>> -    unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
>> +    unsigned SectionID, relocation_iterator RelI,
>> +    const ObjectFile &Obj,
>>      ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
>>      StubMap &Stubs) {
>>    uint64_t RelType;
>> @@ -946,7 +911,7 @@ relocation_iterator RuntimeDyldELF::proc
>>
>>    // Obtain the symbol name which is referenced in the relocation
>>    StringRef TargetName;
>> -  if (Symbol != Obj.end_symbols())
>> +  if (Symbol != Obj.symbol_end())
>>      Symbol->getName(TargetName);
>>    DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
>>                 << " TargetName: " << TargetName << "\n");
>> @@ -954,7 +919,7 @@ relocation_iterator RuntimeDyldELF::proc
>>    // 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.end_symbols()) {
>> +  if (Symbol != Obj.symbol_end()) {
>>      lsi = Symbols.find(TargetName.data());
>>      Symbol->getType(SymType);
>>    }
>> @@ -965,7 +930,7 @@ relocation_iterator RuntimeDyldELF::proc
>>    } else {
>>      // Search for the symbol in the global symbol table
>>      SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end();
>> -    if (Symbol != Obj.end_symbols())
>> +    if (Symbol != Obj.symbol_end())
>>        gsi = GlobalSymbolTable.find(TargetName.data());
>>      if (gsi != GlobalSymbolTable.end()) {
>>        Value.SectionID = gsi->second.first;
>> @@ -977,9 +942,9 @@ relocation_iterator RuntimeDyldELF::proc
>>          // 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.end_sections());
>> +        section_iterator si(Obj.section_end());
>>          Symbol->getSection(si);
>> -        if (si == Obj.end_sections())
>> +        if (si == Obj.section_end())
>>            llvm_unreachable("Symbol section not found, bad object file format!");
>>          DEBUG(dbgs() << "\t\tThis is section symbol\n");
>>          bool isCode = si->isText();
>> @@ -1135,7 +1100,7 @@ relocation_iterator RuntimeDyldELF::proc
>>      if (RelType == ELF::R_PPC64_REL24) {
>>        // Determine ABI variant in use for this object.
>>        unsigned AbiVariant;
>> -      Obj.getObjectFile()->getPlatformFlags(AbiVariant);
>> +      Obj.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
>> @@ -1495,7 +1460,7 @@ uint64_t RuntimeDyldELF::findGOTEntry(ui
>>    return 0;
>>  }
>>
>> -void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg,
>> +void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
>>                                    ObjSectionToIDMap &SectionMap) {
>>    // If necessary, allocate the global offset table
>>    if (MemMgr) {
>> @@ -1533,15 +1498,8 @@ void RuntimeDyldELF::finalizeLoad(Object
>>    }
>>  }
>>
>> -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();
>> +bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const {
>> +  return Obj.isELF();
>>  }
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Wed Nov 26 00:53:26 2014
>> @@ -28,9 +28,11 @@ std::error_code Check(std::error_code Er
>>    }
>>    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);
>> @@ -81,9 +83,11 @@ class RuntimeDyldELF : public RuntimeDyl
>>        return 1;
>>    }
>>
>> -  void findPPC64TOCSection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
>> +  void findPPC64TOCSection(const ObjectFile &Obj,
>> +                           ObjSectionToIDMap &LocalSections,
>>                             RelocationValueRef &Rel);
>> -  void findOPDEntrySection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
>> +  void findOPDEntrySection(const ObjectFile &Obj,
>> +                           ObjSectionToIDMap &LocalSections,
>>                             RelocationValueRef &Rel);
>>
>>    uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
>> @@ -104,24 +108,23 @@ class RuntimeDyldELF : public RuntimeDyl
>>    SmallVector<SID, 2> RegisteredEHFrameSections;
>>
>>  public:
>> -  RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
>> +  RuntimeDyldELF(RTDyldMemoryManager *mm);
>> +  virtual ~RuntimeDyldELF();
>> +
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
>> +  loadObject(const object::ObjectFile &O) override;
>>
>>    void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
>>    relocation_iterator
>>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,
>> -                       ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
>> +                       const ObjectFile &Obj,
>> +                       ObjSectionToIDMap &ObjSectionToID,
>>                         const SymbolTableMap &Symbols, StubMap &Stubs) override;
>> -  bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
>> -  bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
>> +  bool isCompatibleFile(const object::ObjectFile &Obj) const override;
>>    void registerEHFrames() override;
>>    void deregisterEHFrames() override;
>> -  void finalizeLoad(ObjectImage &ObjImg,
>> +  void finalizeLoad(const ObjectFile &Obj,
>>                      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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Wed Nov 26 00:53:26 2014
>> @@ -18,7 +18,6 @@
>>  #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"
>> @@ -37,7 +36,6 @@ using namespace llvm::object;
>>
>>  namespace llvm {
>>
>> -class ObjectBuffer;
>>  class Twine;
>>
>>  /// SectionEntry - represents a section emitted into memory by the dynamic
>> @@ -159,6 +157,7 @@ public:
>>  };
>>
>>  class RuntimeDyldImpl {
>> +  friend class RuntimeDyld::LoadedObjectInfo;
>>    friend class RuntimeDyldCheckerImpl;
>>  private:
>>
>> @@ -296,14 +295,15 @@ protected:
>>    /// \brief Given the common symb...
>>
>> [Message clipped]


On Wed, Nov 26, 2014 at 9:49 AM, Aaron Ballman <aaron at aaronballman.com> wrote:
> On Wed, Nov 26, 2014 at 1:53 AM, Lang Hames <lhames at gmail.com> wrote:
>> Author: lhames
>> Date: Wed Nov 26 00:53:26 2014
>> New Revision: 222810
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=222810&view=rev
>> Log:
>> [MCJIT] Clean up RuntimeDyld's quirky object-ownership/modification scheme.
>>
>> Previously, when loading an object file, RuntimeDyld (1) took ownership of the
>> ObjectFile instance (and associated MemoryBuffer), (2) potentially modified the
>> object in-place, and (3) returned an ObjectImage that managed ownership of the
>> now-modified object and provided some convenience methods. This scheme accreted
>> over several years as features were tacked on to RuntimeDyld, and was both
>> unintuitive and unsafe (See e.g. http://llvm.org/PR20722).
>>
>> This patch fixes the issue by removing all ownership and in-place modification
>> of object files from RuntimeDyld. Existing behavior, including debugger
>> registration, is preserved.
>>
>> Noteworthy changes include:
>>
>> (1) ObjectFile instances are now passed to RuntimeDyld by const-ref.
>> (2) The ObjectImage and ObjectBuffer classes have been removed entirely, they
>>     existed to model ownership within RuntimeDyld, and so are no longer needed.
>> (3) RuntimeDyld::loadObject now returns an instance of a new class,
>>     RuntimeDyld::LoadedObjectInfo, which can be used to construct a modified
>>     object suitable for registration with the debugger, following the existing
>>     debugger registration scheme.
>> (4) The JITRegistrar class has been removed, and the GDBRegistrar class has been
>>     re-written as a JITEventListener.
>>
>> This should fix http://llvm.org/PR20722 .
>>
>>
>> Added:
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h
>>       - copied, changed from r222801, llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp
>>       - copied, changed from r222764, llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>> Removed:
>>     llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>>     llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
>>     llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
>> Modified:
>>     llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
>>     llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
>>     llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
>>     llvm/trunk/lib/ExecutionEngine/CMakeLists.txt
>>     llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
>>     llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>>     llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
>>     llvm/trunk/tools/lli/RemoteMemoryManager.cpp
>>     llvm/trunk/tools/lli/RemoteMemoryManager.h
>>     llvm/trunk/tools/llvm-jitlistener/llvm-jitlistener.cpp
>>     llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h Wed Nov 26 00:53:26 2014
>> @@ -15,6 +15,7 @@
>>  #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"
>> @@ -25,7 +26,10 @@ class Function;
>>  class MachineFunction;
>>  class OProfileWrapper;
>>  class IntelJITEventsWrapper;
>> -class ObjectImage;
>> +
>> +namespace object {
>> +  class ObjectFile;
>> +}
>>
>>  /// JITEvent_EmittedFunctionDetails - Helper struct for containing information
>>  /// about a generated machine code function.
>> @@ -57,7 +61,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
>> @@ -67,11 +71,15 @@ 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 ObjectImage &Obj) {}
>> +  virtual void NotifyObjectEmitted(const object::ObjectFile &Obj,
>> +                                   const RuntimeDyld::LoadedObjectInfo &L) {}
>>
>>    /// NotifyFreeingObject - Called just before the memory associated with
>>    /// a previously emitted object is released.
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
>> +  virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {}
>> +
>> +  // Get a pointe to the GDB debugger registration listener.
>> +  static JITEventListener *createGDBRegistrationListener();
>>
>>  #if LLVM_USE_INTEL_JITEVENTS
>>    // Construct an IntelJITEventListener
>> @@ -105,7 +113,8 @@ public:
>>      return nullptr;
>>    }
>>  #endif // USE_OPROFILE
>> -
>> +private:
>> +  virtual void anchor();
>>  };
>>
>>  } // end namespace llvm.
>>
>> Removed: llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (removed)
>> @@ -1,76 +0,0 @@
>> -//===---- 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
>>
>> Removed: llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h (removed)
>> @@ -1,76 +0,0 @@
>> -//===---- 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
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h Wed Nov 26 00:53:26 2014
>> @@ -22,7 +22,10 @@
>>  namespace llvm {
>>
>>  class ExecutionEngine;
>> -class ObjectImage;
>> +
>> +  namespace object {
>> +    class ObjectFile;
>> +  }
>>
>>  // RuntimeDyld clients often want to handle the memory management of
>>  // what gets placed where. For JIT clients, this is the subset of
>> @@ -109,7 +112,7 @@ public:
>>    /// address space can use this call to remap the section addresses for the
>>    /// newly loaded object.
>>    virtual void notifyObjectLoaded(ExecutionEngine *EE,
>> -                                  const ObjectImage *) {}
>> +                                  const object::ObjectFile &) {}
>>
>>    /// This method is called when object loading is complete and section page
>>    /// permissions can be applied.  It is up to the memory manager implementation
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Wed Nov 26 00:53:26 2014
>> @@ -15,19 +15,19 @@
>>  #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,22 +46,35 @@ 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();
>>
>> -  /// 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);
>> +  /// Add the referenced object file to the list of objects to be loaded and
>> +  /// relocated.
>> +  std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O);
>>
>>    /// 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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/CMakeLists.txt?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/ExecutionEngine/CMakeLists.txt Wed Nov 26 00:53:26 2014
>> @@ -3,7 +3,6 @@
>>  add_llvm_library(LLVMExecutionEngine
>>    ExecutionEngine.cpp
>>    ExecutionEngineBindings.cpp
>> -  JITEventListener.cpp
>>    RTDyldMemoryManager.cpp
>>    TargetSelect.cpp
>>    )
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Wed Nov 26 00:53:26 2014
>> @@ -16,8 +16,7 @@
>>  #include "llvm/ADT/SmallString.h"
>>  #include "llvm/ADT/Statistic.h"
>>  #include "llvm/ExecutionEngine/GenericValue.h"
>> -#include "llvm/ExecutionEngine/ObjectBuffer.h"
>> -#include "llvm/ExecutionEngine/ObjectCache.h"
>> +#include "llvm/ExecutionEngine/JITEventListener.h"
>>  #include "llvm/IR/Constants.h"
>>  #include "llvm/IR/DataLayout.h"
>>  #include "llvm/IR/DerivedTypes.h"
>> @@ -43,17 +42,15 @@ 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) {
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -21,7 +21,6 @@
>>  #include "llvm/ADT/DenseMap.h"
>>  #include "llvm/CodeGen/MachineFunction.h"
>>  #include "llvm/DebugInfo/DIContext.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>>  #include "llvm/Object/ObjectFile.h"
>>  #include "llvm/Support/Debug.h"
>>  #include "llvm/Support/raw_ostream.h"
>> @@ -32,6 +31,7 @@
>>
>>  using namespace llvm;
>>  using namespace llvm::jitprofiling;
>> +using namespace llvm::object;
>>
>>  #define DEBUG_TYPE "amplifier-jit-event-listener"
>>
>> @@ -48,6 +48,7 @@ class IntelJITEventListener : public JIT
>>    typedef DenseMap<const void *, MethodAddressVector>  ObjectMap;
>>
>>    ObjectMap  LoadedObjectMap;
>> +  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
>>
>>  public:
>>    IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
>> @@ -57,9 +58,10 @@ public:
>>    ~IntelJITEventListener() {
>>    }
>>
>> -  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
>> +  void NotifyObjectEmitted(const ObjectFile &Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L) override;
>>
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj);
>> +  void NotifyFreeingObject(const ObjectFile &Obj) override;
>>  };
>>
>>  static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress,
>> @@ -95,23 +97,29 @@ static iJIT_Method_Load FunctionDescToIn
>>    return Result;
>>  }
>>
>> -void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
>> +void IntelJITEventListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Obj,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +
>> +  OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
>> +  const ObjectFile &DebugObj = *DebugObjOwner.getBinary();
>> +
>>    // Get the address of the object image for use as a unique identifier
>> -  const void* ObjData = Obj.getData().data();
>> -  DIContext* Context = DIContext::getDWARFContext(*Obj.getObjectFile());
>> +  const void* ObjData = DebugObj.getData().data();
>> +  DIContext* Context = DIContext::getDWARFContext(DebugObj);
>>    MethodAddressVector Functions;
>>
>>    // Use symbol info to iterate functions in the object.
>> -  for (object::symbol_iterator I = Obj.begin_symbols(),
>> -                               E = Obj.end_symbols();
>> +  for (symbol_iterator I = DebugObj.symbol_begin(),
>> +                       E = DebugObj.symbol_end();
>>                          I != E;
>>                          ++I) {
>>      std::vector<LineNumberInfo> LineInfo;
>>      std::string SourceFileName;
>>
>> -    object::SymbolRef::Type SymType;
>> +    SymbolRef::Type SymType;
>>      if (I->getType(SymType)) continue;
>> -    if (SymType == object::SymbolRef::ST_Function) {
>> +    if (SymType == SymbolRef::ST_Function) {
>>        StringRef  Name;
>>        uint64_t   Addr;
>>        uint64_t   Size;
>> @@ -162,11 +170,18 @@ void IntelJITEventListener::NotifyObject
>>    // registered function addresses for each loaded object.  We will
>>    // use the MethodIDs map to get the registered ID for each function.
>>    LoadedObjectMap[ObjData] = Functions;
>> +  DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
>>  }
>>
>> -void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
>> +void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
>> +  // This object may not have been registered with the listener. If it wasn't,
>> +  // bail out.
>> +  if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end())
>> +    return;
>> +
>>    // Get the address of the object image for use as a unique identifier
>> -  const void* ObjData = Obj.getData().data();
>> +  const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary();
>> +  const void* ObjData = DebugObj.getData().data();
>>
>>    // Get the object's function list from LoadedObjectMap
>>    ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
>> @@ -190,6 +205,7 @@ void IntelJITEventListener::NotifyFreein
>>
>>    // Erase the object from LoadedObjectMap
>>    LoadedObjectMap.erase(OI);
>> +  DebugObjects.erase(Obj.getData().data());
>>  }
>>
>>  }  // anonymous namespace.
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/JITEventListener.cpp (removed)
>> @@ -1,15 +0,0 @@
>> -//===-- 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() {}
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Wed Nov 26 00:53:26 2014
>> @@ -11,8 +11,6 @@
>>  #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"
>> @@ -21,6 +19,7 @@
>>  #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"
>> @@ -31,6 +30,8 @@
>>
>>  using namespace llvm;
>>
>> +void ObjectCache::anchor() {}
>> +
>>  namespace {
>>
>>  static struct RegisterJIT {
>> @@ -74,6 +75,7 @@ MCJIT::MCJIT(std::unique_ptr<Module> M,
>>
>>    OwnedModules.addModule(std::move(First));
>>    setDataLayout(TM->getSubtargetImpl()->getDataLayout());
>> +  RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
>>  }
>>
>>  MCJIT::~MCJIT() {
>> @@ -99,13 +101,13 @@ bool MCJIT::removeModule(Module *M) {
>>  }
>>
>>  void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
>> -  std::unique_ptr<ObjectImage> LoadedObject = Dyld.loadObject(std::move(Obj));
>> -  if (!LoadedObject || Dyld.hasError())
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
>> +  if (Dyld.hasError())
>>      report_fatal_error(Dyld.getErrorString());
>>
>> -  NotifyObjectEmitted(*LoadedObject);
>> +  NotifyObjectEmitted(*Obj, *L);
>>
>> -  LoadedObjects.push_back(std::move(LoadedObject));
>> +  LoadedObjects.push_back(std::move(Obj));
>>  }
>>
>>  void MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
>> @@ -125,7 +127,7 @@ void MCJIT::setObjectCache(ObjectCache*
>>    ObjCache = NewCache;
>>  }
>>
>> -std::unique_ptr<ObjectBufferStream> MCJIT::emitObject(Module *M) {
>> +std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
>>    MutexGuard locked(lock);
>>
>>    // This must be a module which has already been added but not loaded to this
>> @@ -138,30 +140,32 @@ std::unique_ptr<ObjectBufferStream> MCJI
>>    PM.add(new DataLayoutPass());
>>
>>    // The RuntimeDyld will take ownership of this shortly
>> -  std::unique_ptr<ObjectBufferStream> CompiledObject(new ObjectBufferStream());
>> +  SmallVector<char, 4096> ObjBufferSV;
>> +  raw_svector_ostream ObjStream(ObjBufferSV);
>>
>>    // Turn the machine code intermediate representation into bytes in memory
>>    // that may be executed.
>> -  if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(),
>> -                            !getVerifyModules())) {
>> +  if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !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
>> -  CompiledObject->flush();
>> +  ObjStream.flush();
>> +
>> +  std::unique_ptr<MemoryBuffer> CompiledObjBuffer(
>> +                                new ObjectMemoryBuffer(std::move(ObjBufferSV)));
>>
>>    // 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 = CompiledObject->getMemBuffer();
>> +    MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
>>      ObjCache->notifyObjectCompiled(M, MB);
>>    }
>>
>> -  return CompiledObject;
>> +  return CompiledObjBuffer;
>>  }
>>
>>  void MCJIT::generateCodeForModule(Module *M) {
>> @@ -176,14 +180,10 @@ void MCJIT::generateCodeForModule(Module
>>    if (OwnedModules.hasModuleBeenLoaded(M))
>>      return;
>>
>> -  std::unique_ptr<ObjectBuffer> ObjectToLoad;
>> +  std::unique_ptr<MemoryBuffer> ObjectToLoad;
>>    // Try to load the pre-compiled object from cache if possible
>> -  if (ObjCache) {
>> -    if (std::unique_ptr<MemoryBuffer> PreCompiledObject =
>> -            ObjCache->getObject(M))
>> -      ObjectToLoad =
>> -          llvm::make_unique<ObjectBuffer>(std::move(PreCompiledObject));
>> -  }
>> +  if (ObjCache)
>> +    ObjectToLoad = ObjCache->getObject(M);
>>
>>    // If the cache did not contain a suitable object, compile the object
>>    if (!ObjectToLoad) {
>> @@ -193,17 +193,18 @@ void MCJIT::generateCodeForModule(Module
>>
>>    // Load the object into the dynamic linker.
>>    // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
>> -  std::unique_ptr<ObjectImage> LoadedObject =
>> -      Dyld.loadObject(std::move(ObjectToLoad));
>> -  if (!LoadedObject)
>> -    report_fatal_error(Dyld.getErrorString());
>> +  ErrorOr<std::unique_ptr<object::ObjectFile>> LoadedObject =
>> +    object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
>> +  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
>> +    Dyld.loadObject(*LoadedObject.get());
>>
>> -  // FIXME: Make this optional, maybe even move it to a JIT event listener
>> -  LoadedObject->registerWithDebugger();
>> +  if (Dyld.hasError())
>> +    report_fatal_error(Dyld.getErrorString());
>>
>> -  NotifyObjectEmitted(*LoadedObject);
>> +  NotifyObjectEmitted(*LoadedObject.get(), *L);
>>
>> -  LoadedObjects.push_back(std::move(LoadedObject));
>> +  Buffers.push_back(std::move(ObjectToLoad));
>> +  LoadedObjects.push_back(std::move(*LoadedObject));
>>
>>    OwnedModules.markModuleAsLoaded(M);
>>  }
>> @@ -549,6 +550,7 @@ void MCJIT::RegisterJITEventListener(JIT
>>    MutexGuard locked(lock);
>>    EventListeners.push_back(L);
>>  }
>> +
>>  void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
>>    if (!L)
>>      return;
>> @@ -559,14 +561,17 @@ void MCJIT::UnregisterJITEventListener(J
>>      EventListeners.pop_back();
>>    }
>>  }
>> -void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {
>> +
>> +void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj,
>> +                                const RuntimeDyld::LoadedObjectInfo &L) {
>>    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);
>> +    EventListeners[I]->NotifyObjectEmitted(Obj, L);
>>    }
>>  }
>> -void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) {
>> +
>> +void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) {
>>    MutexGuard locked(lock);
>>    for (JITEventListener *L : EventListeners)
>>      L->NotifyFreeingObject(Obj);
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Wed Nov 26 00:53:26 2014
>> @@ -10,12 +10,12 @@
>>  #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 ObjectImage *Obj) override {
>> +                          const object::ObjectFile &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<ObjectImage>, 2> LoadedObjects;
>> +  SmallVector<std::unique_ptr<object::ObjectFile>, 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,10 +341,11 @@ 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<ObjectBufferStream> emitObject(Module *M);
>> +  std::unique_ptr<MemoryBuffer> emitObject(Module *M);
>>
>> -  void NotifyObjectEmitted(const ObjectImage& Obj);
>> -  void NotifyFreeingObject(const ObjectImage& Obj);
>> +  void NotifyObjectEmitted(const object::ObjectFile& Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L);
>> +  void NotifyFreeingObject(const object::ObjectFile& Obj);
>>
>>    uint64_t getExistingSymbolAddress(const std::string &Name);
>>    Module *findModuleForSymbol(const std::string &Name,
>>
>> Copied: llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h (from r222801, llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h)
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h?p2=llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h&p1=llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h&r1=222801&r2=222810&rev=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/ObjectBuffer.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/ObjectBuffer.h Wed Nov 26 00:53:26 2014
>> @@ -1,4 +1,4 @@
>> -//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
>> +//===--- ObjectBuffer.h - Utility class to wrap object memory ---*- C++ -*-===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -21,54 +21,26 @@
>>
>>  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();
>> +class ObjectMemoryBuffer : public MemoryBuffer {
>>  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();
>> +  template <unsigned N>
>> +  ObjectMemoryBuffer(SmallVector<char, N> SV)
>> +    : SV(SV), BufferName("<in-memory object>") {
>> +    init(this->SV.begin(), this->SV.end(), false);
>>    }
>>
>> -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);
>> +  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; }
>>
>> -protected:
>> -  SmallVector<char, 4096> SV; // Working buffer into which we JIT.
>> -  raw_svector_ostream     OS; // streaming wrapper
>> +private:
>> +  SmallVector<char, 4096> SV;
>> +  std::string BufferName;
>>  };
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -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"
>> @@ -31,31 +31,34 @@
>>
>>  using namespace llvm;
>>  using namespace llvm::jitprofiling;
>> +using namespace llvm::object;
>>
>>  #define DEBUG_TYPE "oprofile-jit-event-listener"
>>
>>  namespace {
>>
>>  class OProfileJITEventListener : public JITEventListener {
>> -  OProfileWrapper& Wrapper;
>> +  std::unique_ptr<OProfileWrapper> Wrapper;
>>
>>    void initialize();
>> +  std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
>>
>>  public:
>> -  OProfileJITEventListener(OProfileWrapper& LibraryWrapper)
>> -  : Wrapper(LibraryWrapper) {
>> +  OProfileJITEventListener(std::unique_ptr<OProfileWrapper> LibraryWrapper)
>> +    : Wrapper(std::move(LibraryWrapper)) {
>>      initialize();
>>    }
>>
>>    ~OProfileJITEventListener();
>>
>> -  virtual void NotifyObjectEmitted(const ObjectImage &Obj);
>> +  void NotifyObjectEmitted(const ObjectFile &Obj,
>> +                           const RuntimeDyld::LoadedObjectInfo &L) override;
>>
>> -  virtual void NotifyFreeingObject(const ObjectImage &Obj);
>> +  void NotifyFreeingObject(const ObjectFile &Obj) override;
>>  };
>>
>>  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 {
>> @@ -64,8 +67,8 @@ void OProfileJITEventListener::initializ
>>  }
>>
>>  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");
>> @@ -75,17 +78,22 @@ OProfileJITEventListener::~OProfileJITEv
>>    }
>>  }
>>
>> -void OProfileJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
>> -  if (!Wrapper.isAgentAvailable()) {
>> +void OProfileJITEventListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Obj,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +  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 (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
>> +  for (symbol_iterator I = DebugObj.symbol_begin(), E = DebugObj.symbol_end();
>>         I != E; ++I) {
>> -    object::SymbolRef::Type SymType;
>> +    SymbolRef::Type SymType;
>>      if (I->getType(SymType)) continue;
>> -    if (SymType == object::SymbolRef::ST_Function) {
>> +    if (SymType == SymbolRef::ST_Function) {
>>        StringRef  Name;
>>        uint64_t   Addr;
>>        uint64_t   Size;
>> @@ -93,7 +101,7 @@ void OProfileJITEventListener::NotifyObj
>>        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 ["
>> @@ -103,45 +111,48 @@ void OProfileJITEventListener::NotifyObj
>>        // TODO: support line number info (similar to IntelJITEventListener.cpp)
>>      }
>>    }
>> -}
>>
>> -void OProfileJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
>> -  if (!Wrapper.isAgentAvailable()) {
>> -    return;
>> -  }
>> +  DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
>> +}
>>
>> -  // 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;
>> +void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
>> +  if (Wrapper->isAgentAvailable()) {
>>
>> -      if (Wrapper.op_unload_native_code(Addr) == -1) {
>> -        DEBUG(dbgs()
>> -          << "Failed to tell OProfile about unload of native function at "
>> -          << (void*)Addr << "\n");
>> -        continue;
>> +    // 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;
>> +        }
>>        }
>>      }
>>    }
>> +
>> +  DebugObjects.erase(Obj.getData().data());
>>  }
>>
>>  }  // anonymous namespace.
>>
>>  namespace llvm {
>>  JITEventListener *JITEventListener::createOProfileJITEventListener() {
>> -  static std::unique_ptr<OProfileWrapper> JITProfilingWrapper(
>> -      new OProfileWrapper);
>> -  return new OProfileJITEventListener(*JITProfilingWrapper);
>> -}
>> -
>> -// for testing
>> -JITEventListener *JITEventListener::createOProfileJITEventListener(
>> -                                      OProfileWrapper* TestImpl) {
>> -  return new OProfileJITEventListener(*TestImpl);
>> +  return new OProfileJITEventListener(llvm::make_unique<OProfileWrapper>());
>>  }
>>
>>  } // namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt Wed Nov 26 00:53:26 2014
>> @@ -1,5 +1,5 @@
>>  add_llvm_library(LLVMRuntimeDyld
>> -  GDBRegistrar.cpp
>> +  GDBRegistrationListener.cpp
>>    RuntimeDyld.cpp
>>    RuntimeDyldChecker.cpp
>>    RuntimeDyldELF.cpp
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (removed)
>> @@ -1,213 +0,0 @@
>> -//===-- 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
>>
>> Copied: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp (from r222764, llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp)
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp?p2=llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp&p1=llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp&r1=222764&r2=222810&rev=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp Wed Nov 26 00:53:26 2014
>> @@ -1,4 +1,4 @@
>> -//===-- GDBRegistrar.cpp - Registers objects with GDB ---------------------===//
>> +//===----- GDBRegistrationListener.cpp - Registers objects with GDB -------===//
>>  //
>>  //                     The LLVM Compiler Infrastructure
>>  //
>> @@ -7,8 +7,9 @@
>>  //
>>  //===----------------------------------------------------------------------===//
>>
>> -#include "JITRegistrar.h"
>>  #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"
>> @@ -16,6 +17,7 @@
>>  #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" {
>> @@ -60,37 +62,49 @@ extern "C" {
>>
>>  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*,
>> -                        std::pair<std::size_t, jit_code_entry*> >
>> +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 GDBJITRegistrar : public JITRegistrar {
>> +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.
>> -  GDBJITRegistrar() : ObjectBufferMap() {}
>> +  GDBJITRegistrationListener() : ObjectBufferMap() {}
>>
>>    /// Unregisters each object that was previously registered and releases all
>>    /// internal resources.
>> -  virtual ~GDBJITRegistrar();
>> +  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 registerObject(const ObjectBuffer &Object) override;
>> +  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.
>> -  bool deregisterObject(const ObjectBuffer &Object) override;
>> +  void NotifyFreeingObject(const ObjectFile &Object) override;
>>
>>  private:
>>    /// Deregister the debug info for the given object file from the debugger
>> @@ -119,10 +133,11 @@ void NotifyDebugger(jit_code_entry* JITC
>>    __jit_debug_register_code();
>>  }
>>
>> -GDBJITRegistrar::~GDBJITRegistrar() {
>> +GDBJITRegistrationListener::~GDBJITRegistrationListener() {
>>    // Free all registered object files.
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end();
>> +  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.
>> @@ -131,14 +146,19 @@ GDBJITRegistrar::~GDBJITRegistrar() {
>>    ObjectBufferMap.clear();
>>  }
>>
>> -void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) {
>> +void GDBJITRegistrationListener::NotifyObjectEmitted(
>> +                                       const ObjectFile &Object,
>> +                                       const RuntimeDyld::LoadedObjectInfo &L) {
>> +
>> +  OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Object);
>> +  const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
>> +  size_t      Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
>>
>> -  const char *Buffer = Object.getBufferStart();
>> -  size_t      Size = Object.getBufferSize();
>> +  const char *Key = Object.getMemoryBufferRef().getBufferStart();
>>
>> -  assert(Buffer && "Attempt to register a null object with a debugger.");
>> +  assert(Key && "Attempt to register a null object with a debugger.");
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  assert(ObjectBufferMap.find(Buffer) == ObjectBufferMap.end() &&
>> +  assert(ObjectBufferMap.find(Key) == ObjectBufferMap.end() &&
>>           "Second attempt to perform debug registration.");
>>    jit_code_entry* JITCodeEntry = new jit_code_entry();
>>
>> @@ -149,28 +169,27 @@ void GDBJITRegistrar::registerObject(con
>>      JITCodeEntry->symfile_addr = Buffer;
>>      JITCodeEntry->symfile_size = Size;
>>
>> -    ObjectBufferMap[Buffer] = std::make_pair(Size, JITCodeEntry);
>> +    ObjectBufferMap[Key] = RegisteredObjectInfo(Size, JITCodeEntry,
>> +                                                std::move(DebugObj));
>
> This broke the build with MSVC -- it turns out that MSVC is attempting
> to copy the RegisteredObjectInfo object into the DenseMap, which
> triggers a use of the deleted unique_ptr::operator= (implicitly
> created for OwningBinary).
>
> http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/11753/steps/build_llvm/logs/stdio
>
> ~Aaron
>
>>      NotifyDebugger(JITCodeEntry);
>>    }
>>  }
>>
>> -bool GDBJITRegistrar::deregisterObject(const ObjectBuffer& Object) {
>> -  const char *Buffer = Object.getBufferStart();
>> +void GDBJITRegistrationListener::NotifyFreeingObject(const ObjectFile& Object) {
>> +  const char *Key = Object.getMemoryBufferRef().getBufferStart();
>>    llvm::MutexGuard locked(*JITDebugLock);
>> -  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer);
>> +  RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Key);
>>
>>    if (I != ObjectBufferMap.end()) {
>>      deregisterObjectInternal(I);
>>      ObjectBufferMap.erase(I);
>> -    return true;
>>    }
>> -  return false;
>>  }
>>
>> -void GDBJITRegistrar::deregisterObjectInternal(
>> +void GDBJITRegistrationListener::deregisterObjectInternal(
>>      RegisteredObjectBufferMap::iterator I) {
>>
>> -  jit_code_entry*& JITCodeEntry = I->second.second;
>> +  jit_code_entry*& JITCodeEntry = I->second.Entry;
>>
>>    // Do the unregistration.
>>    {
>> @@ -200,14 +219,14 @@ void GDBJITRegistrar::deregisterObjectIn
>>    JITCodeEntry = nullptr;
>>  }
>>
>> -llvm::ManagedStatic<GDBJITRegistrar> TheRegistrar;
>> +llvm::ManagedStatic<GDBJITRegistrationListener> GDBRegListener;
>>
>>  } // end namespace
>>
>>  namespace llvm {
>>
>> -JITRegistrar& JITRegistrar::getGDBRegistrar() {
>> -  return *TheRegistrar;
>> +JITEventListener* JITEventListener::createGDBRegistrationListener() {
>> +  return &*GDBRegListener;
>>  }
>>
>>  } // namespace llvm
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h (removed)
>> @@ -1,44 +0,0 @@
>> -//===-- 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
>>
>> Removed: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h?rev=222809&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (removed)
>> @@ -1,86 +0,0 @@
>> -//===-- 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
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Wed Nov 26 00:53:26 2014
>> @@ -12,8 +12,6 @@
>>  //===----------------------------------------------------------------------===//
>>
>>  #include "llvm/ExecutionEngine/RuntimeDyld.h"
>> -#include "JITRegistrar.h"
>> -#include "ObjectImageCommon.h"
>>  #include "RuntimeDyldCheckerImpl.h"
>>  #include "RuntimeDyldELF.h"
>>  #include "RuntimeDyldImpl.h"
>> @@ -30,10 +28,8 @@ using namespace llvm::object;
>>  // Empty out-of-line virtual destructor as the key function.
>>  RuntimeDyldImpl::~RuntimeDyldImpl() {}
>>
>> -// Pin the JITRegistrar's and ObjectImage*'s vtables to this file.
>> -void JITRegistrar::anchor() {}
>> -void ObjectImage::anchor() {}
>> -void ObjectImageCommon::anchor() {}
>> +// Pin LoadedObjectInfo's vtables to this file.
>> +void RuntimeDyld::LoadedObjectInfo::anchor() {}
>>
>>  namespace llvm {
>>
>> @@ -139,22 +135,23 @@ static std::error_code getOffset(const S
>>    return object_error::success;
>>  }
>>
>> -std::unique_ptr<ObjectImage>
>> -RuntimeDyldImpl::loadObject(std::unique_ptr<ObjectImage> Obj) {
>> +std::pair<unsigned, unsigned>
>> +RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
>>    MutexGuard locked(lock);
>>
>> -  if (!Obj)
>> -    return nullptr;
>> +  // Grab the first Section ID. We'll use this later to construct the underlying
>> +  // range for the returned LoadedObjectInfo.
>> +  unsigned SectionsAddedBeginIdx = Sections.size();
>>
>>    // Save information about our target
>> -  Arch = (Triple::ArchType)Obj->getArch();
>> -  IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian();
>> +  Arch = (Triple::ArchType)Obj.getArch();
>> +  IsTargetLittleEndian = Obj.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);
>>    }
>>
>> @@ -170,7 +167,7 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>    // Parse symbols
>>    DEBUG(dbgs() << "Parse symbols:\n");
>> -  for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E;
>> +  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
>>         ++I) {
>>      object::SymbolRef::Type SymType;
>>      StringRef Name;
>> @@ -196,15 +193,15 @@ RuntimeDyldImpl::loadObject(std::unique_
>>            SymType == object::SymbolRef::ST_Unknown) {
>>          uint64_t SectOffset;
>>          StringRef SectionData;
>> -        section_iterator SI = Obj->end_sections();
>> +        section_iterator SI = Obj.section_end();
>>          Check(getOffset(*I, SectOffset));
>>          Check(I->getSection(SI));
>> -        if (SI == Obj->end_sections())
>> +        if (SI == Obj.section_end())
>>            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);
>> @@ -216,11 +213,11 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>    // 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->begin_sections(), SE = Obj->end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      unsigned SectionID = 0;
>>      StubMap Stubs;
>> @@ -234,23 +231,25 @@ RuntimeDyldImpl::loadObject(std::unique_
>>
>>      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->getImageName(), SectionID, Stubs);
>> +      Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
>>    }
>>
>>    // Give the subclasses a chance to tie-up any loose ends.
>> -  finalizeLoad(*Obj, LocalSections);
>> +  finalizeLoad(Obj, LocalSections);
>>
>> -  return Obj;
>> +  unsigned SectionsAddedEndIdx = Sections.size();
>> +
>> +  return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
>>  }
>>
>>  // A helper method for computeTotalAllocSize.
>> @@ -270,7 +269,7 @@ computeAllocationSizeForSections(std::ve
>>
>>  // Compute an upper bound of the memory size that is required to load all
>>  // sections
>> -void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
>> +void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
>>                                              uint64_t &CodeSize,
>>                                              uint64_t &DataSizeRO,
>>                                              uint64_t &DataSizeRW) {
>> @@ -282,7 +281,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>
>>    // Collect sizes of all sections to be loaded;
>>    // also determine the max alignment of all sections
>> -  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      const SectionRef &Section = *SI;
>>
>> @@ -328,7 +327,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>
>>    // Compute the size of all common symbols
>>    uint64_t CommonSize = 0;
>> -  for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
>> +  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
>>         ++I) {
>>      uint32_t Flags = I->getFlags();
>>      if (Flags & SymbolRef::SF_Common) {
>> @@ -353,7 +352,7 @@ void RuntimeDyldImpl::computeTotalAllocS
>>  }
>>
>>  // compute stub buffer size for the given section
>> -unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
>>                                                      const SectionRef &Section) {
>>    unsigned StubSize = getMaxStubSize();
>>    if (StubSize == 0) {
>> @@ -363,7 +362,7 @@ unsigned RuntimeDyldImpl::computeSection
>>    // necessary section allocation size in loadObject by walking all the sections
>>    // once.
>>    unsigned StubBufSize = 0;
>> -  for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
>> +  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
>>         SI != SE; ++SI) {
>>      section_iterator RelSecI = SI->getRelocatedSection();
>>      if (!(RelSecI == Section))
>> @@ -418,7 +417,7 @@ void RuntimeDyldImpl::writeBytesUnaligne
>>    }
>>  }
>>
>> -void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
>> +void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
>>                                          const CommonSymbolMap &CommonSymbols,
>>                                          uint64_t TotalSize,
>>                                          SymbolTableMap &SymbolTable) {
>> @@ -450,14 +449,13 @@ void RuntimeDyldImpl::emitCommonSymbols(
>>        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(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
>>                                        const SectionRef &Section, bool IsCode) {
>>
>>    StringRef data;
>> @@ -521,7 +519,6 @@ unsigned RuntimeDyldImpl::emitSection(Ob
>>                   << " 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
>> @@ -537,12 +534,12 @@ unsigned RuntimeDyldImpl::emitSection(Ob
>>    Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
>>
>>    if (Checker)
>> -    Checker->registerSection(Obj.getImageName(), SectionID);
>> +    Checker->registerSection(Obj.getFileName(), SectionID);
>>
>>    return SectionID;
>>  }
>>
>> -unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj,
>> +unsigned RuntimeDyldImpl::findOrEmitSection(const ObjectFile &Obj,
>>                                              const SectionRef &Section,
>>                                              bool IsCode,
>>                                              ObjSectionToIDMap &LocalSections) {
>> @@ -739,6 +736,16 @@ void RuntimeDyldImpl::resolveExternalSym
>>
>>  //===----------------------------------------------------------------------===//
>>  // 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
>> @@ -772,78 +779,23 @@ createRuntimeDyldMachO(Triple::ArchType
>>    return Dyld;
>>  }
>>
>> -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 (InputObject->isMachO()) {
>> -    InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject)));
>> -    if (!Dyld)
>> -      Dyld = createRuntimeDyldMachO(
>> -          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)
>> +std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
>> +RuntimeDyld::loadObject(const ObjectFile &Obj) {
>> +  if (!Dyld) {
>> +    if (Obj.isELF())
>>        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)
>> +    else if (Obj.isMachO())
>>        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!");
>> +               static_cast<Triple::ArchType>(Obj.getArch()), MM,
>> +               ProcessAllSections, Checker);
>> +    else
>> +      report_fatal_error("Incompatible object format!");
>>    }
>>
>> -  if (!Dyld->isCompatibleFormat(InputBufferPtr))
>> +  if (!Dyld->isCompatibleFile(Obj))
>>      report_fatal_error("Incompatible object format!");
>>
>> -  return Dyld->loadObject(std::move(InputImage));
>> +  return Dyld->loadObject(Obj);
>>  }
>>
>>  void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=222810&r1=222809&r2=222810&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Wed Nov 26 00:53:26 2014
>> @@ -12,27 +12,23 @@
>>  //===----------------------------------------------------------------------===//
>>
>>  #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/ExecutionEngine/ObjectBuffer.h"
>> -#include "llvm/ExecutionEngine/ObjectImage.h"
>> +#include "llvm/MC/MCStreamer.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());
>> @@ -40,6 +36,8 @@ static inline std::error_code check(std:
>>    return Err;
>>  }
>>
>> +namespace {
>> +
>>  template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
>>    LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
>>
>> @@ -52,16 +50,12 @@ template <class ELFT> class DyldELFObjec
>>
>>    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 &Sym, uint64_t Addr);
>> +
>> +  void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr);
>>
>>    // Methods for type inquiry through isa, cast and dyn_cast
>>    static inline bool classof(const Binary *v) {
>> @@ -71,42 +65,10 @@ 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
>> @@ -118,14 +80,6 @@ DyldELFObject<ELFT>::DyldELFObject(Memor
>>  }
>>
>>  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) {
>>    DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
>> @@ -149,10 +103,89 @@ void DyldELFObject<ELFT>::updateSymbolAd
>>    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;
>> @@ -180,83 +213,14 @@ void RuntimeDyldELF::deregisterEHFrames(
>>    RegisteredEHFrameSections.clear();
>>  }
>>
>> -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));
>> +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);
>>  }
>>
>> -RuntimeDyldELF::~RuntimeDyldELF() {}
>> -
>>  void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
>>                                               uint64_t Offset, uint64_t Value,
>>                                               uint32_t Type, int64_t Addend,
>> @@ -615,7 +579,7 @@ void RuntimeDyldELF::resolveMIPSRelocati
>>  }
>>
>>  // Return the .TOC. section and offset.
>> -void RuntimeDyldELF::findPPC64TOCSection(ObjectImage &Obj,
>> +void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
>>                                           ObjSectionToIDMap &LocalSections,
>>                                           RelocationValueRef &Rel) {
>>    // Set a default SectionID in case we do not find a TOC section below.
>> @@ -628,7 +592,7 @@ void RuntimeDyldELF::findPPC64TOCSection
>>
>>    // 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.begin_sections(), se = Obj.end_sections();
>> +  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
>>         si != se; ++si) {
>>
>>      StringRef SectionName;
>> @@ -650,15 +614,15 @@ void RuntimeDyldELF::findPPC64TOCSection
>>
>>  // Returns the sections and offset associated with the ODP entry referenced
>>  // by Symbol.
>> -void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
>> +void RuntimeDyldELF::findOPDEntrySection(const ObjectFile &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.begin_sections(), se = Obj.end_sections();
>> +  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
>>         si != se; ++si) {
>>      section_iterator RelSecI = si->getRelocatedSection();
>> -    if (RelSecI == Obj.end_sections())
>> +    if (RelSecI == Obj.section_end())
>>        continue;
>>
>>      StringRef RelSectionName;
>> @@ -700,7 +664,7 @@ void RuntimeDyldELF::findOPDEntrySection
>>        if (Rel.Addend != (int64_t)TargetSymbolOffset)
>>          continue;
>>
>> -      section_iterator tsi(Obj.end_sections());
>> +      section_iterator tsi(Obj.section_end());
>>        check(TargetSymbol->getSection(tsi));
>>        bool IsCode = tsi->isText();
>>        Rel.SectionID = findOrEmitSection(Obj, (*tsi), IsCode, LocalSections);
>> @@ -935,7 +899,8 @@ void RuntimeDyldELF::resolveRelocation(c
>>  }
>>
>>  relocation_iterator RuntimeDyldELF::processRelocationRef(
>> -    unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
>> +    unsigned SectionID, relocation_iterator RelI,
>> +    const ObjectFile &Obj,
>>      ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
>>      StubMap &Stubs) {
>>    uint64_t RelType;
>> @@ -946,7 +911,7 @@ relocation_iterator RuntimeDyldELF::proc
>>
>>    // Obtain the symbol name which is referenced in the relocation
>>    StringRef TargetName;
>> -  if (Symbol != Obj.end_symbols())
>> +  if (Symbol != Obj.symbol_end())
>>      Symbol->getName(TargetName);
>>    DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
>>                 << " TargetName: " << TargetName << "\n");
>> @@ -954,7 +919,7 @@ relocation_iterator RuntimeDyldELF::proc
>>    // 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.end_symbols()) {
>> +  if (Symbol != Obj.symbol_end()) {
>>      lsi = Symbols.find(TargetName.data());
>>      Symbol->getType(SymType);
>>    }
>> @@ -965,7 +930,7 @@ relocation_iterator RuntimeDyldELF::proc
>>    } else {
>>      // Search for the symbol in the global symbol table
>>      SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end();
>> -    if (Symbol != Obj.end_symbols())
>> +    if (Symbol != Obj.symbol_end())
>>        gsi = GlobalSymbolTable.find(TargetName.data());
>>      if (gsi != GlobalSymbolTable.end()) {
>>        Value.SectionID = gsi->second.first;
>> @@ -977,9 +942,9 @@ relocation_iterator RuntimeDyldELF::proc
>>          // 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.end_sections());
>> +        section_iterator si(Obj.section_end());
>>          Symbol->getSection(si);
>> -        if (si == Obj.end_sections())
>> +        if (si == Obj.section_end())
>>            llvm_unreachable("Symbol section not found, bad object file format!");
>>          DEBUG(dbgs() << "\t\tThis is section symbol\n");
>>          bool isCode = si->isText();
>> @@ -1135,7 +1100,7 @@ relocation_iterator RuntimeDyldELF::proc
>>      if (RelType == ELF::R_PPC64_REL24) {
>>        // Determine ABI variant in use for this object.
>>        unsigned AbiVariant;
>> -      Obj.getObjectFile()->getPlatformFlags(AbiVariant);
>> +      Obj.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
>> @@ -1495,7 +1460,7 @@ uint64_t RuntimeDyldELF::findGOTEntry(ui
>>    return 0;
>>  }
>>
>> -void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg,
>> +void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
>>                                    ObjSectionToIDMap &SectionMap) {
>>    // If necessary, allocate the global offset table
>>    if (MemMgr) {
>> @@ -1533,15 +1498,8
> ...
>
> [Message clipped]




More information about the llvm-commits mailing list