Implement GDB integration for source level debugging of code JITed using
authorPreston Gurd <preston.gurd@intel.com>
Mon, 16 Apr 2012 22:12:58 +0000 (22:12 +0000)
committerPreston Gurd <preston.gurd@intel.com>
Mon, 16 Apr 2012 22:12:58 +0000 (22:12 +0000)
the MCJIT execution engine.

The GDB JIT debugging integration support works by registering a loaded
object image with a pre-defined function that GDB will monitor if GDB
is attached. GDB integration support is implemented for ELF only at this
time. This integration requires GDB version 7.0 or newer.

Patch by Andy Kaylor!

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

include/llvm/Object/ELF.h
lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
lib/Object/ELFObjectFile.cpp

index 0828985f2e9bb6cb4bc1562e23a9e1e756dc6e5d..e493f5bd9296db1cebee3653db4081f385abb9d7 100644 (file)
 namespace llvm {
 namespace object {
 
 namespace llvm {
 namespace object {
 
+// Subclasses of ELFObjectFile may need this for template instantiation
+inline std::pair<unsigned char, unsigned char>
+getElfArchType(MemoryBuffer *Object) {
+  if (Object->getBufferSize() < ELF::EI_NIDENT)
+    return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
+  return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
+                       , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
+}
+
 // Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
 template<support::endianness target_endianness>
 struct ELFDataTypeTypedefHelperCommon {
 // Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
 template<support::endianness target_endianness>
 struct ELFDataTypeTypedefHelperCommon {
index 002e63cd3b6b7eec0ba4ec9635f4ce15ba44a940..cbf7cf14d4915c1f0d9933636ca8df802208dbc5 100644 (file)
@@ -1,5 +1,6 @@
 add_llvm_library(LLVMRuntimeDyld
 add_llvm_library(LLVMRuntimeDyld
+  GDBRegistrar.cpp
   RuntimeDyld.cpp
   RuntimeDyld.cpp
-  RuntimeDyldMachO.cpp
   RuntimeDyldELF.cpp
   RuntimeDyldELF.cpp
+  RuntimeDyldMachO.cpp
   )
   )
index 63cec1aca3b19e4fd037cadc952902b84c4d8718..1b1840ae06618a5863ff098c3e54eb7175061fe1 100644 (file)
@@ -59,11 +59,17 @@ void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
   llvm_unreachable("Attempting to remap address of unknown section!");
 }
 
   llvm_unreachable("Attempting to remap address of unknown section!");
 }
 
+// Subclasses can implement this method to create specialized image instances
+// The caller owns the the pointer that is returned.
+ObjectImage *RuntimeDyldImpl::createObjectImage(const MemoryBuffer *InputBuffer) {
+  ObjectFile *ObjFile = ObjectFile::createObjectFile(const_cast<MemoryBuffer*>
+                                                                 (InputBuffer));
+  ObjectImage *Obj = new ObjectImage(ObjFile);
+  return Obj;
+}
+
 bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
 bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
-  // FIXME: ObjectFile don't modify MemoryBuffer.
-  //        It should use const MemoryBuffer as parameter.
-  OwningPtr<ObjectFile> obj(ObjectFile::createObjectFile(
-                                       const_cast<MemoryBuffer*>(InputBuffer)));
+  OwningPtr<ObjectImage> obj(createObjectImage(InputBuffer));
   if (!obj)
     report_fatal_error("Unable to create object image from memory buffer!");
 
   if (!obj)
     report_fatal_error("Unable to create object image from memory buffer!");
 
@@ -110,7 +116,8 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
                                 (uintptr_t)FileOffset;
         uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin());
         unsigned SectionID =
                                 (uintptr_t)FileOffset;
         uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin());
         unsigned SectionID =
-          findOrEmitSection(*si,
+          findOrEmitSection(*obj,
+                            *si,
                             SymType == object::SymbolRef::ST_Function,
                             LocalSections);
         bool isGlobal = flags & SymbolRef::SF_Global;
                             SymType == object::SymbolRef::ST_Function,
                             LocalSections);
         bool isGlobal = flags & SymbolRef::SF_Global;
@@ -128,7 +135,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
 
   // Allocate common symbols
   if (CommonSize != 0)
 
   // Allocate common symbols
   if (CommonSize != 0)
-    emitCommonSymbols(CommonSymbols, CommonSize, LocalSymbols);
+    emitCommonSymbols(*obj, CommonSymbols, CommonSize, LocalSymbols);
 
   // Parse and proccess relocations
   DEBUG(dbgs() << "Parse relocations:\n");
 
   // Parse and proccess relocations
   DEBUG(dbgs() << "Parse relocations:\n");
@@ -145,7 +152,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
 
       // If it's first relocation in this section, find its SectionID
       if (isFirstRelocation) {
 
       // If it's first relocation in this section, find its SectionID
       if (isFirstRelocation) {
-        SectionID = findOrEmitSection(*si, true, LocalSections);
+        SectionID = findOrEmitSection(*obj, *si, true, LocalSections);
         DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
         isFirstRelocation = false;
       }
         DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
         isFirstRelocation = false;
       }
@@ -164,10 +171,14 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
       processRelocationRef(RI, *obj, LocalSections, LocalSymbols, Stubs);
     }
   }
       processRelocationRef(RI, *obj, LocalSections, LocalSymbols, Stubs);
     }
   }
+
+  handleObjectLoaded(obj.take());
+
   return false;
 }
 
   return false;
 }
 
-unsigned RuntimeDyldImpl::emitCommonSymbols(const CommonSymbolMap &Map,
+unsigned RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
+                                            const CommonSymbolMap &Map,
                                             uint64_t TotalSize,
                                             LocalSymbolMap &LocalSymbols) {
   // Allocate memory for the section
                                             uint64_t TotalSize,
                                             LocalSymbolMap &LocalSymbols) {
   // Allocate memory for the section
@@ -191,6 +202,7 @@ unsigned RuntimeDyldImpl::emitCommonSymbols(const CommonSymbolMap &Map,
     uint64_t Size = it->second;
     StringRef Name;
     it->first.getName(Name);
     uint64_t Size = it->second;
     StringRef Name;
     it->first.getName(Name);
+    Obj.updateSymbolAddress(it->first, (uint64_t)Addr);
     LocalSymbols[Name.data()] = SymbolLoc(SectionID, Offset);
     Offset += Size;
     Addr += Size;
     LocalSymbols[Name.data()] = SymbolLoc(SectionID, Offset);
     Offset += Size;
     Addr += Size;
@@ -199,7 +211,8 @@ unsigned RuntimeDyldImpl::emitCommonSymbols(const CommonSymbolMap &Map,
   return SectionID;
 }
 
   return SectionID;
 }
 
-unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section,
+unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
+                                      const SectionRef &Section,
                                       bool IsCode) {
 
   unsigned StubBufSize = 0,
                                       bool IsCode) {
 
   unsigned StubBufSize = 0,
@@ -257,6 +270,7 @@ unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section,
                  << " StubBufSize: " << StubBufSize
                  << " Allocate: " << Allocate
                  << "\n");
                  << " 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
   }
   else {
     // Even if we didn't load the section, we need to record an entry for it
@@ -277,7 +291,8 @@ unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section,
   return SectionID;
 }
 
   return SectionID;
 }
 
-unsigned RuntimeDyldImpl::findOrEmitSection(const SectionRef &Section,
+unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj,
+                                            const SectionRef &Section,
                                             bool IsCode,
                                             ObjSectionToIDMap &LocalSections) {
 
                                             bool IsCode,
                                             ObjSectionToIDMap &LocalSections) {
 
@@ -286,7 +301,7 @@ unsigned RuntimeDyldImpl::findOrEmitSection(const SectionRef &Section,
   if (i != LocalSections.end())
     SectionID = i->second;
   else {
   if (i != LocalSections.end())
     SectionID = i->second;
   else {
-    SectionID = emitSection(Section, IsCode);
+    SectionID = emitSection(Obj, Section, IsCode);
     LocalSections[Section] = SectionID;
   }
   return SectionID;
     LocalSections[Section] = SectionID;
   }
   return SectionID;
index 57fefee5dedc470522faaa982dd1724872f9b17d..e2ebc342adbbbd715a6c5abe621135f459bcfd3c 100644 (file)
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/Object/ELF.h"
+#include "JITRegistrar.h"
 using namespace llvm;
 using namespace llvm::object;
 
 using namespace llvm;
 using namespace llvm::object;
 
+namespace {
+
+template<support::endianness target_endianness, bool is64Bits>
+class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> {
+  LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+
+  typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
+  typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
+  typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel;
+  typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela;
+
+  typedef typename ELFObjectFile<target_endianness, is64Bits>::
+    Elf_Ehdr Elf_Ehdr;
+
+  typedef typename ELFDataTypeTypedefHelper<
+          target_endianness, is64Bits>::value_type addr_type;
+
+protected:
+  // This duplicates the 'Data' member in the 'Binary' base class
+  // but it is necessary to workaround a bug in gcc 4.2
+  MemoryBuffer *InputData;
+
+public:
+  DyldELFObject(MemoryBuffer *Object, error_code &ec);
+
+  void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
+  void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr);
+
+  const MemoryBuffer& getBuffer() const { return *InputData; }
+
+  // Methods for type inquiry through isa, cast, and dyn_cast
+  static inline bool classof(const Binary *v) {
+    return (isa<ELFObjectFile<target_endianness, is64Bits> >(v)
+            && classof(cast<ELFObjectFile<target_endianness, is64Bits> >(v)));
+  }
+  static inline bool classof(
+      const ELFObjectFile<target_endianness, is64Bits> *v) {
+    return v->isDyldType();
+  }
+  static inline bool classof(const DyldELFObject *v) {
+    return true;
+  }
+};
+
+template<support::endianness target_endianness, bool is64Bits>
+class ELFObjectImage : public ObjectImage {
+  protected:
+    DyldELFObject<target_endianness, is64Bits> *DyldObj;
+    bool Registered;
+
+  public:
+    ELFObjectImage(DyldELFObject<target_endianness, is64Bits> *Obj)
+    : ObjectImage(Obj),
+      DyldObj(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
+    virtual void updateSectionAddress(const SectionRef &Sec, uint64_t Addr)
+    {
+      DyldObj->updateSectionAddress(Sec, Addr);
+    }
+
+    virtual void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr)
+    {
+      DyldObj->updateSymbolAddress(Sym, Addr);
+    }
+
+    virtual void registerWithDebugger()
+    {
+      JITRegistrar::getGDBRegistrar().registerObject(DyldObj->getBuffer());
+      Registered = true;
+    }
+    virtual void deregisterWithDebugger()
+    {
+      JITRegistrar::getGDBRegistrar().deregisterObject(DyldObj->getBuffer());
+    }
+};
+
+template<support::endianness target_endianness, bool is64Bits>
+DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Object,
+                                                          error_code &ec)
+  : ELFObjectFile<target_endianness, is64Bits>(Object, ec),
+    InputData(Object) {
+  this->isDyldELFObject = true;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress(
+                                                       const SectionRef &Sec,
+                                                       uint64_t Addr) {
+  DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
+  Elf_Shdr *shdr = const_cast<Elf_Shdr*>(
+                          reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
+
+  // This assumes the address passed in matches the target address bitness
+  // The template-based type cast handles everything else.
+  shdr->sh_addr = static_cast<addr_type>(Addr);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress(
+                                                       const SymbolRef &SymRef,
+                                                       uint64_t Addr) {
+
+  Elf_Sym *sym = const_cast<Elf_Sym*>(
+                                 ELFObjectFile<target_endianness, is64Bits>::
+                                   getSymbol(SymRef.getRawDataRefImpl()));
+
+  // This assumes the address passed in matches the target address bitness
+  // The template-based type cast handles everything else.
+  sym->st_value = static_cast<addr_type>(Addr);
+}
+
+} // namespace
+
+
 namespace llvm {
 
 namespace llvm {
 
+ObjectImage *RuntimeDyldELF::createObjectImage(
+                                         const MemoryBuffer *ConstInputBuffer) {
+  MemoryBuffer *InputBuffer = const_cast<MemoryBuffer*>(ConstInputBuffer);
+  std::pair<unsigned char, unsigned char> Ident = getElfArchType(InputBuffer);
+  error_code ec;
+
+  if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
+    DyldELFObject<support::little, false> *Obj =
+           new DyldELFObject<support::little, false>(InputBuffer, ec);
+    return new ELFObjectImage<support::little, false>(Obj);
+  }
+  else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) {
+    DyldELFObject<support::big, false> *Obj =
+           new DyldELFObject<support::big, false>(InputBuffer, ec);
+    return new ELFObjectImage<support::big, false>(Obj);
+  }
+  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) {
+    DyldELFObject<support::big, true> *Obj =
+           new DyldELFObject<support::big, true>(InputBuffer, ec);
+    return new ELFObjectImage<support::big, true>(Obj);
+  }
+  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
+    DyldELFObject<support::little, true> *Obj =
+           new DyldELFObject<support::little, true>(InputBuffer, ec);
+    return new ELFObjectImage<support::little, true>(Obj);
+  }
+  else
+    llvm_unreachable("Unexpected ELF format");
+}
+
+void RuntimeDyldELF::handleObjectLoaded(ObjectImage *Obj)
+{
+  Obj->registerWithDebugger();
+  // Save the loaded object.  It will deregister itself when deleted
+  LoadedObject = Obj;
+}
+
+RuntimeDyldELF::~RuntimeDyldELF() {
+  if (LoadedObject)
+    delete LoadedObject;
+}
 
 void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
                                              uint64_t FinalAddress,
 
 void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
                                              uint64_t FinalAddress,
@@ -167,7 +332,7 @@ void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress,
 }
 
 void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
 }
 
 void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
-                                          const ObjectFile &Obj,
+                                          ObjectImage &Obj,
                                           ObjSectionToIDMap &ObjSectionToID,
                                           LocalSymbolMap &Symbols,
                                           StubMap &Stubs) {
                                           ObjSectionToIDMap &ObjSectionToID,
                                           LocalSymbolMap &Symbols,
                                           StubMap &Stubs) {
@@ -206,7 +371,7 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
           if (si == Obj.end_sections())
             llvm_unreachable("Symbol section not found, bad object file format!");
           DEBUG(dbgs() << "\t\tThis is section symbol\n");
           if (si == Obj.end_sections())
             llvm_unreachable("Symbol section not found, bad object file format!");
           DEBUG(dbgs() << "\t\tThis is section symbol\n");
-          Value.SectionID = findOrEmitSection((*si), true, ObjSectionToID);
+          Value.SectionID = findOrEmitSection(Obj, (*si), true, ObjSectionToID);
           Value.Addend = Addend;
           break;
         }
           Value.Addend = Addend;
           break;
         }
index 36566da57a58b6707a3fa34c12c5ecd8c887b9c2..e7f6fab16fcbd88a9154e2380c6ee9beb30cc97b 100644 (file)
@@ -22,6 +22,8 @@ using namespace llvm;
 namespace llvm {
 class RuntimeDyldELF : public RuntimeDyldImpl {
 protected:
 namespace llvm {
 class RuntimeDyldELF : public RuntimeDyldImpl {
 protected:
+  ObjectImage *LoadedObject;
+
   void resolveX86_64Relocation(uint8_t *LocalAddress,
                                uint64_t FinalAddress,
                                uint64_t Value,
   void resolveX86_64Relocation(uint8_t *LocalAddress,
                                uint64_t FinalAddress,
                                uint64_t Value,
@@ -47,12 +49,18 @@ protected:
                                  int64_t Addend);
 
   virtual void processRelocationRef(const ObjRelocationInfo &Rel,
                                  int64_t Addend);
 
   virtual void processRelocationRef(const ObjRelocationInfo &Rel,
-                                    const ObjectFile &Obj,
+                                    ObjectImage &Obj,
                                     ObjSectionToIDMap &ObjSectionToID,
                                     LocalSymbolMap &Symbols, StubMap &Stubs);
 
                                     ObjSectionToIDMap &ObjSectionToID,
                                     LocalSymbolMap &Symbols, StubMap &Stubs);
 
+  virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer);
+  virtual void handleObjectLoaded(ObjectImage *Obj);
+
 public:
 public:
-  RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
+  RuntimeDyldELF(RTDyldMemoryManager *mm)
+      : RuntimeDyldImpl(mm), LoadedObject(0) {}
+
+  virtual ~RuntimeDyldELF();
 
   bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
 };
 
   bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
 };
index bf678af6ece787fdebe80767b2fa9e1fce700419..2dea13f15cea6a4ead96a108d7dbf0895984f870 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/ADT/Triple.h"
 #include <map>
 #include "llvm/Support/Format.h"
 #include "llvm/ADT/Triple.h"
 #include <map>
 #include "llvm/Support/Format.h"
+#include "ObjectImage.h"
 
 using namespace llvm;
 using namespace llvm::object;
 
 using namespace llvm;
 using namespace llvm::object;
@@ -154,7 +155,8 @@ protected:
 
   /// \brief Emits a section containing common symbols.
   /// \return SectionID.
 
   /// \brief Emits a section containing common symbols.
   /// \return SectionID.
-  unsigned emitCommonSymbols(const CommonSymbolMap &Map,
+  unsigned emitCommonSymbols(ObjectImage &Obj,
+                             const CommonSymbolMap &Map,
                              uint64_t TotalSize,
                              LocalSymbolMap &Symbols);
 
                              uint64_t TotalSize,
                              LocalSymbolMap &Symbols);
 
@@ -162,14 +164,18 @@ protected:
   /// \param IsCode if it's true then allocateCodeSection() will be
   ///        used for emmits, else allocateDataSection() will be used.
   /// \return SectionID.
   /// \param IsCode if it's true then allocateCodeSection() will be
   ///        used for emmits, else allocateDataSection() will be used.
   /// \return SectionID.
-  unsigned emitSection(const SectionRef &Section, bool IsCode);
+  unsigned emitSection(ObjectImage &Obj,
+                       const SectionRef &Section,
+                       bool IsCode);
 
   /// \brief Find Section in LocalSections. If the secton is not found - emit
   ///        it and store in LocalSections.
   /// \param IsCode if it's true then allocateCodeSection() will be
   ///        used for emmits, else allocateDataSection() will be used.
   /// \return SectionID.
 
   /// \brief Find Section in LocalSections. If the secton is not found - emit
   ///        it and store in LocalSections.
   /// \param IsCode if it's true then allocateCodeSection() will be
   ///        used for emmits, else allocateDataSection() will be used.
   /// \return SectionID.
-  unsigned findOrEmitSection(const SectionRef &Section, bool IsCode,
+  unsigned findOrEmitSection(ObjectImage &Obj,
+                             const SectionRef &Section,
+                             bool IsCode,
                              ObjSectionToIDMap &LocalSections);
 
   /// \brief If Value.SymbolName is NULL then store relocation to the
                              ObjSectionToIDMap &LocalSections);
 
   /// \brief If Value.SymbolName is NULL then store relocation to the
@@ -200,11 +206,18 @@ protected:
   /// \brief Parses the object file relocation and store it to Relocations
   ///        or SymbolRelocations. Its depend from object file type.
   virtual void processRelocationRef(const ObjRelocationInfo &Rel,
   /// \brief Parses the object file relocation and store it to Relocations
   ///        or SymbolRelocations. Its depend from object file type.
   virtual void processRelocationRef(const ObjRelocationInfo &Rel,
-                                    const ObjectFile &Obj,
+                                    ObjectImage &Obj,
                                     ObjSectionToIDMap &ObjSectionToID,
                                     LocalSymbolMap &Symbols, StubMap &Stubs) = 0;
 
   void resolveSymbols();
                                     ObjSectionToIDMap &ObjSectionToID,
                                     LocalSymbolMap &Symbols, StubMap &Stubs) = 0;
 
   void resolveSymbols();
+  virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer);
+  virtual void handleObjectLoaded(ObjectImage *Obj)
+  {
+    // Subclasses may choose to retain this image if they have a use for it
+    delete Obj;
+  }
+
 public:
   RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
 
 public:
   RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
 
index 1318b4454255224b8dc73c77f7f326018cd139db..b7f515d6ce658d6d01ae7184e7376b8b0c57093f 100644 (file)
@@ -205,7 +205,7 @@ resolveARMRelocation(uint8_t *LocalAddress,
 }
 
 void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
 }
 
 void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
-                                            const ObjectFile &Obj,
+                                            ObjectImage &Obj,
                                             ObjSectionToIDMap &ObjSectionToID,
                                             LocalSymbolMap &Symbols,
                                             StubMap &Stubs) {
                                             ObjSectionToIDMap &ObjSectionToID,
                                             LocalSymbolMap &Symbols,
                                             StubMap &Stubs) {
@@ -246,7 +246,7 @@ void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
         break;
     }
     assert(si != se && "No section containing relocation!");
         break;
     }
     assert(si != se && "No section containing relocation!");
-    Value.SectionID = findOrEmitSection(*si, true, ObjSectionToID);
+    Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID);
     Value.Addend = *(const intptr_t *)Target;
     if (Value.Addend) {
       // The MachO addend is offset from the current section, we need set it
     Value.Addend = *(const intptr_t *)Target;
     if (Value.Addend) {
       // The MachO addend is offset from the current section, we need set it
index 898b85190e713fb9d74605d9fc3be4e78e661eb9..418d130f6352329358bd9e42d25deb6dd5690988 100644 (file)
@@ -49,7 +49,7 @@ protected:
                             int64_t Addend);
 
   virtual void processRelocationRef(const ObjRelocationInfo &Rel,
                             int64_t Addend);
 
   virtual void processRelocationRef(const ObjRelocationInfo &Rel,
-                                    const ObjectFile &Obj,
+                                    ObjectImage &Obj,
                                     ObjSectionToIDMap &ObjSectionToID,
                                     LocalSymbolMap &Symbols, StubMap &Stubs);
 
                                     ObjSectionToIDMap &ObjSectionToID,
                                     LocalSymbolMap &Symbols, StubMap &Stubs);
 
@@ -59,7 +59,7 @@ public:
                                  uint64_t Value,
                                  uint32_t Type,
                                  int64_t Addend);
                                  uint64_t Value,
                                  uint32_t Type,
                                  int64_t Addend);
-                                 
+
   RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
 
   bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
   RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
 
   bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
index ab5f8108af13a4edde11e06aa8235f60d15df098..663b84ec8b1f2d160b1e7074860a4305abfbd118 100644 (file)
@@ -17,16 +17,6 @@ namespace llvm {
 
 using namespace object;
 
 
 using namespace object;
 
-namespace {
-  std::pair<unsigned char, unsigned char>
-  getElfArchType(MemoryBuffer *Object) {
-    if (Object->getBufferSize() < ELF::EI_NIDENT)
-      return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
-    return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
-                         , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
-  }
-}
-
 // Creates an in-memory object-file by default: createELFObjectFile(Buffer)
 ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
   std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
 // Creates an in-memory object-file by default: createELFObjectFile(Buffer)
 ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
   std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);