<div dir="ltr">Hi Andy,<div><br></div><div>In the following snippet, do you recall what made it necessary to read the value from the object file via Placeholder, rather than from the copied section?</div><div><br></div><div><span style="font-size:13px">+    // Get the placeholder value from the generated object since</span><br style="font-size:13px"><span style="font-size:13px">+    // a previous relocation attempt may have overwritten the loaded version</span><br style="font-size:13px"><span style="font-size:13px">+    uint64_t *Placeholder = reinterpret_cast<uint64_t*>(</span><span style="font-size:13px">Section.ObjAddress</span><br style="font-size:13px"><span style="font-size:13px">+                                                                   + Offset);</span><br style="font-size:13px"><span style="font-size:13px">+    uint64_t *Target = reinterpret_cast<uint64_t*>(</span><span style="font-size:13px">Section.Address + Offset);</span><br style="font-size:13px"><span style="font-size:13px">+    uint64_t  FinalAddress = Section.LoadAddress + Offset;</span><br style="font-size:13px"><span style="font-size:13px">+    *Target = *Placeholder + Value + Addend - FinalAddress;</span><br style="font-size:13px"><span style="font-size:13px">+    break;</span><br></div><div><span style="font-size:13px"><br></span></div><div>I''d like to make my new JIT APIs more aggressive about freeing the ObjectFile instances (ideally we'd be able to free immediately after a call to loadObject), but at the moment I have to hold it at least until resolveRelocations is called.</div><div><br></div><div>I had a quick chat with Tim Northover about this and our guess was that it had something to do with relocations being applied more than once?</div><div><br></div><div>Cheers,<br></div><div>Lang.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 19, 2013 at 4:27 PM, Andrew Kaylor <span dir="ltr"><<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: akaylor<br>
Date: Mon Aug 19 18:27:43 2013<br>
New Revision: 188726<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=188726&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=188726&view=rev</a><br>
Log:<br>
Adding PIC support for ELF on x86_64 platforms<br>
<br>
Modified:<br>
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp<br>
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp<br>
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h<br>
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=188726&r1=188725&r2=188726&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=188726&r1=188725&r2=188726&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Mon Aug 19 18:27:43 2013<br>
@@ -169,6 +169,9 @@ ObjectImage *RuntimeDyldImpl::loadObject<br>
     }<br>
   }<br>
<br>
+  // Give the subclasses a chance to tie-up any loose ends.<br>
+  finalizeLoad();<br>
+<br>
   return obj.take();<br>
 }<br>
<br>
@@ -424,6 +427,10 @@ uint8_t *RuntimeDyldImpl::createStubFunc<br>
     writeInt16BE(Addr+6,  0x07F1);     // brc 15,%r1<br>
     // 8-byte address stored at Addr + 8<br>
     return Addr;<br>
+  } else if (Arch == Triple::x86_64) {<br>
+    *Addr      = 0xFF; // jmp<br>
+    *(Addr+1)  = 0x25; // rip<br>
+    // 32-bit PC-relative address of the GOT entry will be stored at Addr+2<br>
   }<br>
   return Addr;<br>
 }<br>
@@ -473,6 +480,7 @@ void RuntimeDyldImpl::resolveExternalSym<br>
         // MemoryManager.<br>
         uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(),<br>
                                                                    true);<br>
+        updateGOTEntries(Name, (uint64_t)Addr);<br>
         DEBUG(dbgs() << "Resolving relocations Name: " << Name<br>
                 << "\t" << format("%p", Addr)<br>
                 << "\n");<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=188726&r1=188725&r2=188726&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=188726&r1=188725&r2=188726&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Mon Aug 19 18:27:43 2013<br>
@@ -202,7 +202,8 @@ void RuntimeDyldELF::resolveX86_64Reloca<br>
                                              uint64_t Offset,<br>
                                              uint64_t Value,<br>
                                              uint32_t Type,<br>
-                                             int64_t Addend) {<br>
+                                             int64_t  Addend,<br>
+                                             uint64_t SymOffset) {<br>
   switch (Type) {<br>
   default:<br>
     llvm_unreachable("Relocation type not implemented yet!");<br>
@@ -227,6 +228,21 @@ void RuntimeDyldELF::resolveX86_64Reloca<br>
                  << " at " << format("%p\n",Target));<br>
     break;<br>
   }<br>
+  case ELF::R_X86_64_GOTPCREL: {<br>
+    // findGOTEntry returns the 'G + GOT' part of the relocation calculation<br>
+    // based on the load/target address of the GOT (not the current/local addr).<br>
+    uint64_t GOTAddr = findGOTEntry(Value, SymOffset);<br>
+    uint32_t *Target = reinterpret_cast<uint32_t*>(Section.Address + Offset);<br>
+    uint64_t  FinalAddress = Section.LoadAddress + Offset;<br>
+    // The processRelocationRef method combines the symbol offset and the addend<br>
+    // and in most cases that's what we want.  For this relocation type, we need<br>
+    // the raw addend, so we subtract the symbol offset to get it.<br>
+    int64_t RealOffset = GOTAddr + Addend - SymOffset - FinalAddress;<br>
+    assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN);<br>
+    int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);<br>
+    *Target = TruncOffset;<br>
+    break;<br>
+  }<br>
   case ELF::R_X86_64_PC32: {<br>
     // Get the placeholder value from the generated object since<br>
     // a previous relocation attempt may have overwritten the loaded version<br>
@@ -240,6 +256,16 @@ void RuntimeDyldELF::resolveX86_64Reloca<br>
     *Target = TruncOffset;<br>
     break;<br>
   }<br>
+  case ELF::R_X86_64_PC64: {<br>
+    // Get the placeholder value from the generated object since<br>
+    // a previous relocation attempt may have overwritten the loaded version<br>
+    uint64_t *Placeholder = reinterpret_cast<uint64_t*>(Section.ObjAddress<br>
+                                                                   + Offset);<br>
+    uint64_t *Target = reinterpret_cast<uint64_t*>(Section.Address + Offset);<br>
+    uint64_t  FinalAddress = Section.LoadAddress + Offset;<br>
+    *Target = *Placeholder + Value + Addend - FinalAddress;<br>
+    break;<br>
+  }<br>
   }<br>
 }<br>
<br>
@@ -584,7 +610,7 @@ void RuntimeDyldELF::findOPDEntrySection<br>
       // Finally compares the Symbol value and the target symbol offset<br>
       // to check if this .opd entry refers to the symbol the relocation<br>
       // points to.<br>
-      if (Rel.Addend != (intptr_t)TargetSymbolOffset)<br>
+      if (Rel.Addend != (int64_t)TargetSymbolOffset)<br>
         continue;<br>
<br>
       section_iterator tsi(Obj.end_sections());<br>
@@ -757,17 +783,19 @@ void RuntimeDyldELF::resolveSystemZReloc<br>
 void RuntimeDyldELF::resolveRelocation(const RelocationEntry &RE,<br>
                                        uint64_t Value) {<br>
   const SectionEntry &Section = Sections[RE.SectionID];<br>
-  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend);<br>
+  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,<br>
+                           RE.SymOffset);<br>
 }<br>
<br>
 void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,<br>
                                        uint64_t Offset,<br>
                                        uint64_t Value,<br>
                                        uint32_t Type,<br>
-                                       int64_t Addend) {<br>
+                                       int64_t  Addend,<br>
+                                       uint64_t SymOffset) {<br>
   switch (Arch) {<br>
   case Triple::x86_64:<br>
-    resolveX86_64Relocation(Section, Offset, Value, Type, Addend);<br>
+    resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);<br>
     break;<br>
   case Triple::x86:<br>
     resolveX86Relocation(Section, Offset,<br>
@@ -830,6 +858,7 @@ void RuntimeDyldELF::processRelocationRe<br>
   }<br>
   if (lsi != Symbols.end()) {<br>
     Value.SectionID = lsi->second.first;<br>
+    Value.Offset = lsi->second.second;<br>
     Value.Addend = lsi->second.second + Addend;<br>
   } else {<br>
     // Search for the symbol in the global symbol table<br>
@@ -838,6 +867,7 @@ void RuntimeDyldELF::processRelocationRe<br>
       gsi = GlobalSymbolTable.find(TargetName.data());<br>
     if (gsi != GlobalSymbolTable.end()) {<br>
       Value.SectionID = gsi->second.first;<br>
+      Value.Offset = gsi->second.second;<br>
       Value.Addend = gsi->second.second + Addend;<br>
     } else {<br>
       switch (SymType) {<br>
@@ -860,6 +890,7 @@ void RuntimeDyldELF::processRelocationRe<br>
           Value.Addend = Addend;<br>
           break;<br>
         }<br>
+        case SymbolRef::ST_Data:<br>
         case SymbolRef::ST_Unknown: {<br>
           Value.SymbolName = TargetName.data();<br>
           Value.Addend = Addend;<br>
@@ -1150,8 +1181,67 @@ void RuntimeDyldELF::processRelocationRe<br>
                         ELF::R_390_PC32DBL, Addend);<br>
     else<br>
       resolveRelocation(Section, Offset, StubAddress, RelType, Addend);<br>
+  } else if (Arch == Triple::x86_64 && RelType == ELF::R_X86_64_PLT32) {<br>
+    // The way the PLT relocations normally work is that the linker allocates the<br>
+    // PLT and this relocation makes a PC-relative call into the PLT.  The PLT<br>
+    // entry will then jump to an address provided by the GOT.  On first call, the<br>
+    // GOT address will point back into PLT code that resolves the symbol.  After<br>
+    // the first call, the GOT entry points to the actual function.<br>
+    //<br>
+    // For local functions we're ignoring all of that here and just replacing<br>
+    // the PLT32 relocation type with PC32, which will translate the relocation<br>
+    // into a PC-relative call directly to the function. For external symbols we<br>
+    // can't be sure the function will be within 2^32 bytes of the call site, so<br>
+    // we need to create a stub, which calls into the GOT.  This case is<br>
+    // equivalent to the usual PLT implementation except that we use the stub<br>
+    // mechanism in RuntimeDyld (which puts stubs at the end of the section)<br>
+    // rather than allocating a PLT section.<br>
+    if (Value.SymbolName) {<br>
+      // This is a call to an external function.<br>
+      // Look for an existing stub.<br>
+      SectionEntry &Section = Sections[SectionID];<br>
+      StubMap::const_iterator i = Stubs.find(Value);<br>
+      uintptr_t StubAddress;<br>
+      if (i != Stubs.end()) {<br>
+        StubAddress = uintptr_t(Section.Address) + i->second;<br>
+        DEBUG(dbgs() << " Stub function found\n");<br>
+      } else {<br>
+        // Create a new stub function (equivalent to a PLT entry).<br>
+        DEBUG(dbgs() << " Create a new stub function\n");<br>
+<br>
+        uintptr_t BaseAddress = uintptr_t(Section.Address);<br>
+        uintptr_t StubAlignment = getStubAlignment();<br>
+        StubAddress = (BaseAddress + Section.StubOffset +<br>
+                      StubAlignment - 1) & -StubAlignment;<br>
+        unsigned StubOffset = StubAddress - BaseAddress;<br>
+        Stubs[Value] = StubOffset;<br>
+        createStubFunction((uint8_t *)StubAddress);<br>
+<br>
+        // Create a GOT entry for the external function.<br>
+        GOTEntries.push_back(Value);<br>
+<br>
+        // Make our stub function a relative call to the GOT entry.<br>
+        RelocationEntry RE(SectionID, StubOffset + 2,<br>
+                           ELF::R_X86_64_GOTPCREL, -4);<br>
+        addRelocationForSymbol(RE, Value.SymbolName);<br>
+<br>
+        // Bump our stub offset counter<br>
+        Section.StubOffset = StubOffset + getMaxStubSize();<br>
+      }<br>
+<br>
+      // Make the target call a call into the stub table.<br>
+      resolveRelocation(Section, Offset, StubAddress,<br>
+                      ELF::R_X86_64_PC32, Addend);<br>
+    } else {<br>
+      RelocationEntry RE(SectionID, Offset, ELF::R_X86_64_PC32, Value.Addend,<br>
+                         Value.Offset);<br>
+      addRelocationForSection(RE, Value.SectionID);<br>
+    }<br>
   } else {<br>
-    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);<br>
+    if (Arch == Triple::x86_64 && RelType == ELF::R_X86_64_GOTPCREL) {<br>
+      GOTEntries.push_back(Value);<br>
+    }<br>
+    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, Value.Offset);<br>
     if (Value.SymbolName)<br>
       addRelocationForSymbol(RE, Value.SymbolName);<br>
     else<br>
@@ -1159,6 +1249,106 @@ void RuntimeDyldELF::processRelocationRe<br>
   }<br>
 }<br>
<br>
+void RuntimeDyldELF::updateGOTEntries(StringRef Name, uint64_t Addr) {<br>
+  for (int i = 0, e = GOTEntries.size(); i != e; ++i) {<br>
+    if (GOTEntries[i].SymbolName != 0 && GOTEntries[i].SymbolName == Name) {<br>
+      GOTEntries[i].Offset = Addr;<br>
+    }<br>
+  }<br>
+}<br>
+<br>
+size_t RuntimeDyldELF::getGOTEntrySize() {<br>
+  // We don't use the GOT in all of these cases, but it's essentially free<br>
+  // to put them all here.<br>
+  size_t Result = 0;<br>
+  switch (Arch) {<br>
+  case Triple::x86_64:<br>
+  case Triple::aarch64:<br>
+  case Triple::ppc64:<br>
+  case Triple::ppc64le:<br>
+  case Triple::systemz:<br>
+    Result = sizeof(uint64_t);<br>
+    break;<br>
+  case Triple::x86:<br>
+  case Triple::arm:<br>
+  case Triple::thumb:<br>
+  case Triple::mips:<br>
+  case Triple::mipsel:<br>
+    Result = sizeof(uint32_t);<br>
+    break;<br>
+  default: llvm_unreachable("Unsupported CPU type!");<br>
+  }<br>
+  return Result;<br>
+}<br>
+<br>
+uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress,<br>
+                                      uint64_t Offset) {<br>
+  assert(GOTSectionID != 0<br>
+         && "Attempting to lookup GOT entry but the GOT was never allocated.");<br>
+  if (GOTSectionID == 0) {<br>
+    return 0;<br>
+  }<br>
+<br>
+  size_t GOTEntrySize = getGOTEntrySize();<br>
+<br>
+  // Find the matching entry in our vector.<br>
+  int GOTIndex = -1;<br>
+  uint64_t SymbolOffset = 0;<br>
+  for (int i = 0, e = GOTEntries.size(); i != e; ++i) {<br>
+    if (GOTEntries[i].SymbolName == 0) {<br>
+      if (getSectionLoadAddress(GOTEntries[i].SectionID) == LoadAddress &&<br>
+          GOTEntries[i].Offset == Offset) {<br>
+        GOTIndex = i;<br>
+        SymbolOffset = GOTEntries[i].Offset;<br>
+        break;<br>
+      }<br>
+    } else {<br>
+      // GOT entries for external symbols use the addend as the address when<br>
+      // the external symbol has been resolved.<br>
+      if (GOTEntries[i].Offset == LoadAddress) {<br>
+        GOTIndex = i;<br>
+        // Don't use the Addend here.  The relocation handler will use it.<br>
+        break;<br>
+      }<br>
+    }<br>
+  }<br>
+  assert(GOTIndex != -1 && "Unable to find requested GOT entry.");<br>
+  if (GOTIndex == -1)<br>
+    return 0;<br>
+<br>
+  if (GOTEntrySize == sizeof(uint64_t)) {<br>
+    uint64_t *LocalGOTAddr = (uint64_t*)getSectionAddress(GOTSectionID);<br>
+    // Fill in this entry with the address of the symbol being referenced.<br>
+    LocalGOTAddr[GOTIndex] = LoadAddress + SymbolOffset;<br>
+  } else {<br>
+    uint32_t *LocalGOTAddr = (uint32_t*)getSectionAddress(GOTSectionID);<br>
+    // Fill in this entry with the address of the symbol being referenced.<br>
+    LocalGOTAddr[GOTIndex] = (uint32_t)(LoadAddress + SymbolOffset);<br>
+  }<br>
+<br>
+  // Calculate the load address of this entry<br>
+  return getSectionLoadAddress(GOTSectionID) + (GOTIndex * GOTEntrySize);<br>
+}<br>
+<br>
+void RuntimeDyldELF::finalizeLoad() {<br>
+  // Allocate the GOT if necessary<br>
+  size_t numGOTEntries = GOTEntries.size();<br>
+  if (numGOTEntries != 0) {<br>
+    // Allocate memory for the section<br>
+    unsigned SectionID = Sections.size();<br>
+    size_t TotalSize = numGOTEntries * getGOTEntrySize();<br>
+    uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, getGOTEntrySize(),<br>
+                                                SectionID, false);<br>
+    if (!Addr)<br>
+      report_fatal_error("Unable to allocate memory for GOT!");<br>
+    Sections.push_back(SectionEntry(".got", Addr, TotalSize, 0));<br>
+    // For now, initialize all GOT entries to zero.  We'll fill them in as<br>
+    // needed when GOT-based relocations are applied.<br>
+    memset(Addr, 0, TotalSize);<br>
+    GOTSectionID = SectionID;<br>
+  }<br>
+}<br>
+<br>
 bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const {<br>
   if (Buffer->getBufferSize() < strlen(ELF::ElfMagic))<br>
     return false;<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=188726&r1=188725&r2=188726&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=188726&r1=188725&r2=188726&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Mon Aug 19 18:27:43 2013<br>
@@ -35,13 +35,15 @@ class RuntimeDyldELF : public RuntimeDyl<br>
                          uint64_t Offset,<br>
                          uint64_t Value,<br>
                          uint32_t Type,<br>
-                         int64_t Addend);<br>
+                         int64_t Addend,<br>
+                         uint64_t SymOffset=0);<br>
<br>
   void resolveX86_64Relocation(const SectionEntry &Section,<br>
                                uint64_t Offset,<br>
                                uint64_t Value,<br>
                                uint32_t Type,<br>
-                               int64_t Addend);<br>
+                               int64_t  Addend,<br>
+                               uint64_t SymOffset);<br>
<br>
   void resolveX86Relocation(const SectionEntry &Section,<br>
                             uint64_t Offset,<br>
@@ -84,8 +86,18 @@ class RuntimeDyldELF : public RuntimeDyl<br>
                            ObjSectionToIDMap &LocalSections,<br>
                            RelocationValueRef &Rel);<br>
<br>
+  uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);<br>
+  size_t getGOTEntrySize();<br>
+<br>
+  virtual void updateGOTEntries(StringRef Name, uint64_t Addr);<br>
+<br>
+  SmallVector<RelocationValueRef, 2>  GOTEntries;<br>
+  unsigned GOTSectionID;<br>
+<br>
 public:<br>
-  RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}<br>
+  RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm),<br>
+                                            GOTSectionID(0)<br>
+                                          {}<br>
<br>
   virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value);<br>
   virtual void processRelocationRef(unsigned SectionID,<br>
@@ -97,6 +109,7 @@ public:<br>
   virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;<br>
   virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);<br>
   virtual StringRef getEHFrameSection();<br>
+  virtual void finalizeLoad();<br>
   virtual ~RuntimeDyldELF();<br>
 };<br>
<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=188726&r1=188725&r2=188726&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=188726&r1=188725&r2=188726&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Mon Aug 19 18:27:43 2013<br>
@@ -80,14 +80,18 @@ public:<br>
   unsigned SectionID;<br>
<br>
   /// Offset - offset into the section.<br>
-  uintptr_t Offset;<br>
+  uint64_t Offset;<br>
<br>
   /// RelType - relocation type.<br>
   uint32_t RelType;<br>
<br>
   /// Addend - the relocation addend encoded in the instruction itself.  Also<br>
   /// used to make a relocation section relative instead of symbol relative.<br>
-  intptr_t Addend;<br>
+  int64_t Addend;<br>
+<br>
+  /// SymOffset - Section offset of the relocation entry's symbol (used for GOT<br>
+  /// lookup).<br>
+  uint64_t SymOffset;<br>
<br>
   /// True if this is a PCRel relocation (MachO specific).<br>
   bool IsPCRel;<br>
@@ -97,20 +101,26 @@ public:<br>
<br>
   RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend)<br>
     : SectionID(id), Offset(offset), RelType(type), Addend(addend),<br>
-      IsPCRel(false), Size(0) {}<br>
+      SymOffset(0), IsPCRel(false), Size(0) {}<br>
+<br>
+  RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,<br>
+                  uint64_t symoffset)<br>
+    : SectionID(id), Offset(offset), RelType(type), Addend(addend),<br>
+      SymOffset(symoffset), IsPCRel(false), Size(0) {}<br>
<br>
   RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,<br>
                   bool IsPCRel, unsigned Size)<br>
     : SectionID(id), Offset(offset), RelType(type), Addend(addend),<br>
-      IsPCRel(IsPCRel), Size(Size) {}<br>
+      SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}<br>
 };<br>
<br>
 class RelocationValueRef {<br>
 public:<br>
   unsigned  SectionID;<br>
-  intptr_t  Addend;<br>
+  uint64_t  Offset;<br>
+  int64_t   Addend;<br>
   const char *SymbolName;<br>
-  RelocationValueRef(): SectionID(0), Addend(0), SymbolName(0) {}<br>
+  RelocationValueRef(): SectionID(0), Offset(0), Addend(0), SymbolName(0) {}<br>
<br>
   inline bool operator==(const RelocationValueRef &Other) const {<br>
     return std::memcmp(this, &Other, sizeof(RelocationValueRef)) == 0;<br>
@@ -175,7 +185,7 @@ protected:<br>
     else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)<br>
       return 44;<br>
     else if (Arch == Triple::x86_64)<br>
-      return 8; // GOT<br>
+      return 6; // 2-byte jmp instruction + 32-bit relative address<br>
     else if (Arch == Triple::systemz)<br>
       return 16;<br>
     else<br>
@@ -292,6 +302,11 @@ protected:<br>
<br>
   /// \brief Resolve relocations to external symbols.<br>
   void resolveExternalSymbols();<br>
+<br>
+  /// \brief Update GOT entries for external symbols.<br>
+  // The base class does nothing.  ELF overrides this.<br>
+  virtual void updateGOTEntries(StringRef Name, uint64_t Addr) {}<br>
+<br>
   virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);<br>
 public:<br>
   RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}<br>
@@ -336,6 +351,8 @@ public:<br>
   virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0;<br>
<br>
   virtual StringRef getEHFrameSection();<br>
+<br>
+  virtual void finalizeLoad() {}<br>
 };<br>
<br>
 } // end namespace llvm<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>