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

Lang Hames lhames at gmail.com
Mon Feb 2 15:55:42 PST 2015


Hi Keno,

I haven't had a chance to get to it yet. If you have time to check it out
please go for it - it would be very appreciated.

Cheers,
Lang.

On Sun, Feb 1, 2015 at 10:06 PM, Keno Fischer <kfischer at college.harvard.edu>
wrote:

> Hi Lang,
>
> Did you ever make any progress on this? I ran into the same problem when
> rewriting the GOT support (though for a different reason). If not, I can
> take a crack at it, but I wanted to avoid duplicating effort.
>
> Thanks,
> Keno
>
> On Tue, Jan 27, 2015 at 12:07 AM, Lang Hames <lhames at gmail.com> wrote:
>
>> 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
>>>
>>>
>>>
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150202/74809a6f/attachment.html>


More information about the llvm-dev mailing list