[LLVMdev] [llvm] r188726 - Adding PIC support for ELF on x86_64 platforms

Lang Hames lhames at gmail.com
Mon Jan 26 21:07:55 PST 2015


Hi Andy,

Thanks very much for the insight. I'll see if I can come up with a scheme
to support reapplication without having the object file present.

Cheers,
Lang.

On Mon, Jan 26, 2015 at 1:59 PM, Kaylor, Andrew <andrew.kaylor at intel.com>
wrote:

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


More information about the llvm-dev mailing list