[llvm] r234839 - [RuntimeDyldELF] Improve GOT support

Keno Fischer kfischer at college.harvard.edu
Wed Apr 15 02:40:06 PDT 2015


Hi Lang,

see also http://reviews.llvm.org/D9028, which should address this issue
properly. I would suggest to implement a quick fix of not freeing the
object file early if possible (you probably have better insight into the
memory ownership issue here than I do). We can go back to the freeing the
object early once D9028 is sufficient tested and has been merged.

Keno

On Wed, Apr 15, 2015 at 2:34 AM, Keno Fischer <kfischer at college.harvard.edu>
wrote:

> Hi Lang,
>
> I have debugged this after getting MSVC setup in a virtual machine and it
> looks like the object file is getting freed before the relocations are
> applied. Unfortunately, on ELF, we still have the placeholder mechanism
> looking at the original object file, so I suspect this is a use-after-free
> even on other platforms, though we are getting lucky there. I suspect this
> was a problem even without my patch and it's just getting exposed here. How
> does the object file get freed? Is there some way to prevent this?
>
> Keno
>
> On Tue, Apr 14, 2015 at 1:16 PM, Lang Hames <lhames at gmail.com> wrote:
>
>> Looks like SectionEntry was holding the section name as a StringRef.
>> That's not safe now that we can delete the ObjectFile after loading.
>>
>> I've fixed this in r234910. Hopefully you can get more sane output from
>> the test-case now.
>>
>> - Lang.
>>
>> On Tue, Apr 14, 2015 at 8:12 AM, Keno Fischer <
>> kfischer at college.harvard.edu> wrote:
>>
>>> This is missing the second .got section, I believe (hard to tell with
>>> the corrupted names of course). Did llvm-rtdyld get built correctly? Also
>>> CC Lang for why those would be corrupted.
>>>
>>> On Tue, Apr 14, 2015 at 10:51 AM, Kuperstein, Michael M <
>>> michael.m.kuperstein at intel.com> wrote:
>>>
>>>>  Parse symbols:
>>>>
>>>> emitSection SectionID: 0 Name: .text obj addr: 0000000000BA93C0 new
>>>> addr: 0000000000080000 DataSize: 10 StubBufSize: 6 Allocate: 16
>>>>
>>>>         Type: 4 Name: foo SID: 0 Offset: 0000000000000000 flags: 0
>>>>
>>>> Parse relocations:
>>>>
>>>>         SectionID: 0
>>>>
>>>>                 RelType: 9 Addend: -4 TargetName: G
>>>>
>>>>                 SectionID: 0 Offset: 3
>>>>
>>>> Parse symbols:
>>>>
>>>> emitSection SectionID: 2 Name: .bss obj addr: 0000000000000000 new
>>>> addr: 0000000000AA0000 DataSize: 1 StubBufSize: 0 Allocate: 1
>>>>
>>>>         Type: 1 Name: F SID: 2 Offset: 0000000000000000 flags: 66
>>>>
>>>> emitSection SectionID: 3 Name: .data.rel obj addr: 0000000000BA93D0 new
>>>> addr: 0000000000AB0000 DataSize: 8 StubBufSize: 6 Allocate: 14
>>>>
>>>>         Type: 1 Name: G SID: 3 Offset: 0000000000000000 flags: 66
>>>>
>>>> Parse relocations:
>>>>
>>>>         SectionID: 3
>>>>
>>>>                 RelType: 1 Addend: 0 TargetName: F
>>>>
>>>>                 SectionID: 3 Offset: 0
>>>>
>>>> Reassigning address for section 0 (▌▌▌▌▌): 0x0000000000080000 ->
>>>> 0x0000000000001000
>>>>
>>>> Reassigning address for section 1 (.got): 0x0000000000090000 ->
>>>> 0x0000000000011000
>>>>
>>>> Reassigning address for section 2 (▌▌▌▌): 0x0000000000aa0000 ->
>>>> 0x0000000000021000
>>>>
>>>> Reassigning address for section 3 (▌▌▌▌▌▌▌▌▌): 0x0000000000ab0000 ->
>>>> 0x0000000000031000
>>>>
>>>> Resolving relocations Name: G   0x31000
>>>>
>>>> Writing 0000000000031000 at 0000000000090000
>>>>
>>>> Resolving relocations Section #0        0000000000001000
>>>>
>>>> ----- Contents of section ▌▌▌▌▌ before relocations -----
>>>>
>>>> 0x0000000000001000: 48 8b 05 00 00 00 00 8b 00 c3
>>>>
>>>> ----- Contents of section ▌▌▌▌▌ after relocations -----
>>>>
>>>> 0x0000000000001000: 48 8b 05 00 00 00 00 8b 00 c3
>>>>
>>>> Resolving relocations Section #1        0000000000011000
>>>>
>>>> ----- Contents of section .got before relocations -----
>>>>
>>>> 0x0000000000011000: 00 10 03 00 00 00 00 00
>>>>
>>>> Assertion failed: RealOffset <= INT32_MAX && RealOffset >= INT32_MIN,
>>>> file ..\..\..\..\lib\ExecutionEngine\RuntimeDyld\RuntimeDyldELF.cpp, line
>>>> 259
>>>>
>>>>
>>>>
>>>> (The section names are originally printed that way, it’s not the mail
>>>> client’s fault)
>>>>
>>>>
>>>>
>>>> Michael
>>>>
>>>>
>>>>
>>>> *From:* Keno Fischer [mailto:kfischer at college.harvard.edu]
>>>> *Sent:* Tuesday, April 14, 2015 17:18
>>>> *To:* Kuperstein, Michael M
>>>> *Cc:* llvm-commits at cs.uiuc.edu
>>>> *Subject:* Re: [llvm] r234839 - [RuntimeDyldELF] Improve GOT support
>>>>
>>>>
>>>>
>>>> Thanks Michael. I didn't realize that flag was being added on windows,
>>>> but I guess it makes sense, since you're using a non-standard triple for
>>>> MCJIT. I see this was reverted already.
>>>>
>>>>
>>>>
>>>> Regarding the other failure, that's really odd, because this is
>>>> precisely the failure that this commit is supposed to solve. Can you send
>>>> the output of that invocation with `-debug-only dyld` added at the end?
>>>>
>>>>
>>>>
>>>> On Tue, Apr 14, 2015 at 5:57 AM, Kuperstein, Michael M <
>>>> michael.m.kuperstein at intel.com> wrote:
>>>>
>>>> Hello Keno,
>>>>
>>>> Unfortunately, cross-module-sm-pic-a.ll now breaks on windows.
>>>>
>>>> It looks like %lli provides a triple, so this:
>>>> %lli -mtriple=x86_64-pc-linux -extra-module=%p/Inputs/cross-module-b.ll
>>>> -relocation-model=pic -code-model=small %s > /dev/null
>>>>
>>>> Becomes:
>>>> lli.EXE -mtriple=x86_64-pc-win32-elf -mtriple=x86_64-pc-linux
>>>> -extra-module=...
>>>>
>>>> Which (rightfully) gets rejected by lli.
>>>>
>>>> Thanks,
>>>>    Michael
>>>>
>>>>
>>>> -----Original Message-----
>>>> From: llvm-commits-bounces at cs.uiuc.edu [mailto:
>>>> llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Keno Fischer
>>>> Sent: Tuesday, April 14, 2015 05:11
>>>> To: llvm-commits at cs.uiuc.edu
>>>> Subject: [llvm] r234839 - [RuntimeDyldELF] Improve GOT support
>>>>
>>>> Author: kfischer
>>>> Date: Mon Apr 13 21:10:35 2015
>>>> New Revision: 234839
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=234839&view=rev
>>>> Log:
>>>> [RuntimeDyldELF] Improve GOT support
>>>>
>>>> Summary:
>>>> This is the first in a series of patches to eventually add support for
>>>> TLS relocations to RuntimeDyld. This patch resolves an issue in the current
>>>> GOT handling, where GOT entries would be reused between object files, which
>>>> leads to the same situation that necessitates the GOT in the first place,
>>>> i.e. that the 32-bit offset can not cover all of the address space. Thus
>>>> this patch makes the GOT object-file-local.
>>>> Unfortunately, this still isn't quite enough, because the MemoryManager
>>>> does not yet guarantee that sections are allocated sufficiently close to
>>>> each other, even if they belong to the same object file. To address this
>>>> concern, this patch also adds a small API abstraction on top of the GOT
>>>> allocation mechanism that will allow (temporarily, until the MemoryManager
>>>> is improved) using the stub mechanism instead of allocating a different
>>>> section. The actual switch from separate section to stub mechanism will be
>>>> part of a follow-on commit, so that it can be easily reverted independently
>>>> at the appropriate time.
>>>>
>>>> Test Plan: Includes a test case where the GOT of two object files is
>>>> artificially forced to be apart by several GB.
>>>>
>>>> Reviewers: lhames
>>>>
>>>> Reviewed By: lhames
>>>>
>>>> Subscribers: llvm-commits
>>>>
>>>> Differential Revision: http://reviews.llvm.org/D8813
>>>>
>>>> Added:
>>>>
>>>> llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x64-64_PIC_relocations.s
>>>>     llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/
>>>>
>>>> llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ExternalGlobal.ll
>>>> Modified:
>>>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>>>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
>>>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>>>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>>>>     llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>>>>     llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll
>>>>
>>>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=234839&r1=234838&r2=234839&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>>>> (original)
>>>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Mon Apr
>>>>
>>>> +++ 13 21:10:35 2015
>>>> @@ -814,7 +814,6 @@ void RuntimeDyldImpl::resolveExternalSym
>>>>          report_fatal_error("Program used external function '" + Name +
>>>>                             "' which could not be resolved!");
>>>>
>>>> -      updateGOTEntries(Name, Addr);
>>>>        DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"
>>>>                     << format("0x%lx", Addr) << "\n");
>>>>        // This list may have been updated when we called
>>>> getSymbolAddress, so
>>>>
>>>> Modified:
>>>> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h?rev=234839&r1=234838&r2=234839&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
>>>> (original)
>>>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
>>>> +++ Mon Apr 13 21:10:35 2015
>>>> @@ -19,6 +19,7 @@ class RuntimeDyldCheckerImpl {
>>>>    friend class RuntimeDyldChecker;
>>>>    friend class RuntimeDyldImpl;
>>>>    friend class RuntimeDyldCheckerExprEval;
>>>> +  friend class RuntimeDyldELF;
>>>>
>>>>  public:
>>>>    RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld, MCDisassembler
>>>> *Disassembler,
>>>>
>>>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=234839&r1=234838&r2=234839&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
>>>> (original)
>>>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Mon
>>>> +++ Apr 13 21:10:35 2015
>>>>
>>>> @@ -12,6 +12,7 @@
>>>>
>>>>  //===----------------------------------------------------------------------===//
>>>>
>>>>  #include "RuntimeDyldELF.h"
>>>> +#include "RuntimeDyldCheckerImpl.h"
>>>>  #include "llvm/ADT/IntervalMap.h"
>>>>  #include "llvm/ADT/STLExtras.h"
>>>>  #include "llvm/ADT/StringRef.h"
>>>> @@ -185,7 +186,7 @@ namespace llvm {
>>>>
>>>>  RuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
>>>>                                 RuntimeDyld::SymbolResolver &Resolver)
>>>> -    : RuntimeDyldImpl(MemMgr, Resolver) {}
>>>> +    : RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0),
>>>> + CurrentGOTIndex(0) {}
>>>>  RuntimeDyldELF::~RuntimeDyldELF() {}
>>>>
>>>>  void RuntimeDyldELF::registerEHFrames() { @@ -245,27 +246,16 @@ void
>>>> RuntimeDyldELF::resolveX86_64Reloca
>>>>                   << format("%p\n", Section.Address + Offset));
>>>>      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);
>>>> -    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);
>>>> -    support::ulittle32_t::ref(Section.Address + Offset) = 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
>>>>      support::ulittle32_t::ref Placeholder(
>>>>          (void *)(Section.ObjAddress + Offset));
>>>>      uint64_t FinalAddress = Section.LoadAddress + Offset;
>>>> -    int64_t RealOffset = Placeholder + Value + Addend - FinalAddress;
>>>> +    int64_t RealOffset = Value + Addend - FinalAddress;
>>>> +    // Don't add the placeholder if this is a stub
>>>> +    if (Offset < Section.Size)
>>>> +      RealOffset += Placeholder;
>>>>      assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN);
>>>>      int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
>>>>      support::ulittle32_t::ref(Section.Address + Offset) = TruncOffset;
>>>> @@ -277,8 +267,10 @@ void RuntimeDyldELF::resolveX86_64Reloca
>>>>      support::ulittle64_t::ref Placeholder(
>>>>          (void *)(Section.ObjAddress + Offset));
>>>>      uint64_t FinalAddress = Section.LoadAddress + Offset;
>>>> -    support::ulittle64_t::ref(Section.Address + Offset) =
>>>> -        Placeholder + Value + Addend - FinalAddress;
>>>> +    int64_t RealOffset = Value + Addend - FinalAddress;
>>>> +    if (Offset < Section.Size)
>>>> +      RealOffset += Placeholder;
>>>> +    support::ulittle64_t::ref(Section.Address + Offset) = RealOffset;
>>>>      break;
>>>>    }
>>>>    }
>>>> @@ -1323,16 +1315,18 @@ relocation_iterator RuntimeDyldELF::proc
>>>>          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();
>>>> +
>>>> +        // Allocate a GOT Entry
>>>> +        uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
>>>> +
>>>> +        // The load of the GOT address has an addend of -4
>>>> +        resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset
>>>> + - 4);
>>>> +
>>>> +        // Fill in the value of the symbol we're targeting into the GOT
>>>> +
>>>> addRelocationForSymbol(computeGOTOffsetRE(SectionID,GOTOffset,0,ELF::R_X86_64_64),
>>>> +            Value.SymbolName);
>>>>        }
>>>>
>>>>        // Make the target call a call into the stub table.
>>>> @@ -1343,10 +1337,17 @@ relocation_iterator RuntimeDyldELF::proc
>>>>                           Value.Offset);
>>>>        addRelocationForSection(RE, Value.SectionID);
>>>>      }
>>>> +  } else if (Arch == Triple::x86_64 && RelType ==
>>>> ELF::R_X86_64_GOTPCREL) {
>>>> +    uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
>>>> +    resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend);
>>>> +
>>>> +    // Fill in the value of the symbol we're targeting into the GOT
>>>> +    RelocationEntry RE = computeGOTOffsetRE(SectionID, GOTOffset,
>>>> Value.Offset, ELF::R_X86_64_64);
>>>> +    if (Value.SymbolName)
>>>> +      addRelocationForSymbol(RE, Value.SymbolName);
>>>> +    else
>>>> +      addRelocationForSection(RE, Value.SectionID);
>>>>    } else {
>>>> -    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); @@ -1356,22
>>>> +1357,6 @@ relocation_iterator RuntimeDyldELF::proc
>>>>    return ++RelI;
>>>>  }
>>>>
>>>> -void RuntimeDyldELF::updateGOTEntries(StringRef Name, uint64_t Addr) {
>>>> -
>>>> -  SmallVectorImpl<std::pair<SID, GOTRelocations>>::iterator it;
>>>> -  SmallVectorImpl<std::pair<SID, GOTRelocations>>::iterator end =
>>>> GOTs.end();
>>>> -
>>>> -  for (it = GOTs.begin(); it != end; ++it) {
>>>> -    GOTRelocations &GOTEntries = it->second;
>>>> -    for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
>>>> -      if (GOTEntries[i].SymbolName != nullptr &&
>>>> -          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.
>>>> @@ -1398,75 +1383,50 @@ size_t RuntimeDyldELF::getGOTEntrySize()
>>>>    return Result;
>>>>  }
>>>>
>>>> -uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t
>>>> Offset) {
>>>> -
>>>> -  const size_t GOTEntrySize = getGOTEntrySize();
>>>> -
>>>> -  SmallVectorImpl<std::pair<SID, GOTRelocations>>::const_iterator it;
>>>> -  SmallVectorImpl<std::pair<SID, GOTRelocations>>::const_iterator end =
>>>> -      GOTs.end();
>>>> -
>>>> -  int GOTIndex = -1;
>>>> -  for (it = GOTs.begin(); it != end; ++it) {
>>>> -    SID GOTSectionID = it->first;
>>>> -    const GOTRelocations &GOTEntries = it->second;
>>>> -
>>>> -    // Find the matching entry in our vector.
>>>> -    uint64_t SymbolOffset = 0;
>>>> -    for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
>>>> -      if (!GOTEntries[i].SymbolName) {
>>>> -        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;
>>>> -        }
>>>> -      }
>>>> -    }
>>>> -
>>>> -    if (GOTIndex != -1) {
>>>> -      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);
>>>> -    }
>>>> -  }
>>>> -
>>>> -  assert(GOTIndex != -1 && "Unable to find requested GOT entry.");
>>>> -  return 0;
>>>> +uint64_t RuntimeDyldELF::allocateGOTEntries(unsigned SectionID,
>>>>
>>>> +unsigned no) {
>>>> +  (void)SectionID; // The GOT Section is the same for all section in
>>>> +the object file
>>>> +  if (GOTSectionID == 0) {
>>>> +    GOTSectionID = Sections.size();
>>>> +    // Reserve a section id. We'll allocate the section later
>>>> +    // once we know the total size
>>>> +    Sections.push_back(SectionEntry(".got", 0, 0, 0));
>>>> +  }
>>>> +  uint64_t StartOffset = CurrentGOTIndex * getGOTEntrySize();
>>>> +  CurrentGOTIndex += no;
>>>> +  return StartOffset;
>>>> +}
>>>> +
>>>> +void RuntimeDyldELF::resolveGOTOffsetRelocation(unsigned SectionID,
>>>> +uint64_t Offset, uint64_t GOTOffset) {
>>>> +  // Fill in the relative address of the GOT Entry into the stub
>>>> +  RelocationEntry GOTRE(SectionID, Offset, ELF::R_X86_64_PC32,
>>>> +GOTOffset);
>>>> +  addRelocationForSection(GOTRE, GOTSectionID); }
>>>> +
>>>> +RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(unsigned SectionID,
>>>> uint64_t GOTOffset, uint64_t SymbolOffset,
>>>> +                                                   uint32_t Type) {
>>>> +  (void)SectionID; // The GOT Section is the same for all section in
>>>> +the object file
>>>>
>>>> +  return RelocationEntry(GOTSectionID, GOTOffset, Type, SymbolOffset);
>>>>  }
>>>>
>>>>  void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
>>>>                                    ObjSectionToIDMap &SectionMap) {
>>>>    // If necessary, allocate the global offset table
>>>> -  size_t numGOTEntries = GOTEntries.size();
>>>> -  if (numGOTEntries != 0) {
>>>> +  if (GOTSectionID != 0) {
>>>>      // Allocate memory for the section
>>>> -    unsigned SectionID = Sections.size();
>>>> -    size_t TotalSize = numGOTEntries * getGOTEntrySize();
>>>> +    size_t TotalSize = CurrentGOTIndex * getGOTEntrySize();
>>>>      uint8_t *Addr = MemMgr.allocateDataSection(TotalSize,
>>>> getGOTEntrySize(),
>>>> -                                               SectionID, ".got",
>>>> false);
>>>> +                                                GOTSectionID, ".got",
>>>> + false);
>>>>      if (!Addr)
>>>>        report_fatal_error("Unable to allocate memory for GOT!");
>>>>
>>>> -    GOTs.push_back(std::make_pair(SectionID, GOTEntries));
>>>> -    Sections.push_back(SectionEntry(".got", Addr, TotalSize, 0));
>>>> +    Sections[GOTSectionID] = SectionEntry(".got", Addr, TotalSize, 0);
>>>> +
>>>> +    if (Checker)
>>>> +      Checker->registerSection(Obj.getFileName(), GOTSectionID);
>>>> +
>>>>      // 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);
>>>> @@ -1483,6 +1443,9 @@ void RuntimeDyldELF::finalizeLoad(const
>>>>        break;
>>>>      }
>>>>    }
>>>> +
>>>> +  GOTSectionID = 0;
>>>> +  CurrentGOTIndex = 0;
>>>>  }
>>>>
>>>>  bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj)
>>>> const {
>>>>
>>>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=234839&r1=234838&r2=234839&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
>>>> (original)
>>>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Mon Apr
>>>>
>>>> +++ 13 21:10:35 2015
>>>> @@ -80,16 +80,32 @@ class RuntimeDyldELF : public RuntimeDyl
>>>>                             ObjSectionToIDMap &LocalSections,
>>>>                             RelocationValueRef &Rel);
>>>>
>>>> -  uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
>>>>    size_t getGOTEntrySize();
>>>>
>>>> -  void updateGOTEntries(StringRef Name, uint64_t Addr) override;
>>>> +  SectionEntry &getSection(unsigned SectionID) { return
>>>> + Sections[SectionID]; }
>>>>
>>>> -  // Relocation entries for symbols whose position-independent offset
>>>> is
>>>> -  // updated in a global offset table.
>>>> -  typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
>>>> -  GOTRelocations GOTEntries; // List of entries requiring finalization.
>>>> -  SmallVector<std::pair<SID, GOTRelocations>, 8> GOTs; // Allocated
>>>> tables.
>>>> +  // Allocate no GOT entries for use in the given section.
>>>> +  uint64_t allocateGOTEntries(unsigned SectionID, unsigned no);
>>>> +
>>>> +  // Resolve the relvative address of GOTOffset in Section ID and place
>>>> + // it at the given Offset  void resolveGOTOffsetRelocation(unsigned
>>>> + SectionID, uint64_t Offset,
>>>> +                                  uint64_t GOTOffset);
>>>> +
>>>> +  // For a GOT entry referenced from SectionID, compute a relocation
>>>> + entry  // that will place the final resolved value in the GOT slot
>>>> + RelocationEntry computeGOTOffsetRE(unsigned SectionID,
>>>> +                                     uint64_t GOTOffset,
>>>> +                                     uint64_t SymbolOffset,
>>>> +                                     unsigned Type);
>>>> +
>>>> +  // The tentative ID for the GOT section  unsigned GOTSectionID;
>>>> +
>>>> +  // Records the current number of allocated slots in the GOT  // (This
>>>> + would be equivalent to GOTEntries.size() were it not for relocations
>>>> + // that consume more than one slot)  unsigned CurrentGOTIndex;
>>>>
>>>>    // When a module is loaded we save the SectionID of the EH frame
>>>> section
>>>>    // in a table until we receive a request to register all unregistered
>>>>
>>>> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=234839&r1=234838&r2=234839&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>>>> (original)
>>>> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Mon Apr
>>>> +++ 13 21:10:35 2015
>>>> @@ -361,10 +361,6 @@ 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) {}
>>>> -
>>>>    // \brief Compute an upper bound of the memory that is required to
>>>> load all
>>>>    // sections
>>>>    void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize,
>>>>
>>>> Modified: llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll?rev=234839&r1=234838&r2=234839&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll
>>>> (original)
>>>> +++ llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll Mon
>>>> +++ Apr 13 21:10:35 2015
>>>> @@ -1,4 +1,5 @@
>>>>  ; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll
>>>> -relocation-model=pic -code-model=small %s > /dev/null
>>>> +; RUN: %lli -mtriple=x86_64-pc-linux
>>>> +-extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic
>>>> +-code-model=small %s > /dev/null
>>>>  ; XFAIL: mips, i686, i386
>>>>
>>>>  declare i32 @FB()
>>>>
>>>> Added:
>>>> llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x64-64_PIC_relocations.s
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x64-64_PIC_relocations.s?rev=234839&view=auto
>>>>
>>>> ==============================================================================
>>>> ---
>>>> llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x64-64_PIC_relocations.s
>>>> (added)
>>>> +++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x64-64_PIC_reloc
>>>> +++ ations.s Mon Apr 13 21:10:35 2015
>>>> @@ -0,0 +1,31 @@
>>>> +# RUN: llvm-mc -triple=x86_64-pc-linux -relocation-model=pic
>>>> +-filetype=obj -o %T/test_ELF1_x86-64.o %s # RUN: llvm-mc
>>>> +-triple=x86_64-pc-linux -relocation-model=pic -filetype=obj -o
>>>> +%T/test_ELF2_x86-64.o %s # RUN: llc -mtriple=x86_64-pc-linux
>>>> +-relocation-model=pic -filetype=obj -o
>>>> +%T/test_ELF_ExternalGlobal_x86-64.o %S/Inputs/ExternalGlobal.ll # RUN:
>>>> +llvm-rtdyld -triple=x86_64-pc-linux -verify %T/test_ELF1_x86-64.o
>>>> +%T/test_ELF_ExternalGlobal_x86-64.o
>>>> +# Test that we can load this code twice at memory locations more than
>>>> +2GB apart # RUN: llvm-rtdyld -triple=x86_64-pc-linux -verify
>>>> +-map-section test_ELF1_x86-64.o,.got=0x10000 -map-section
>>>> +test_ELF2_x86-64.o,.text=0x100000000 -map-section
>>>> +test_ELF2_x86-64.o,.got=0x100010000 %T/test_ELF1_x86-64.o
>>>> +%T/test_ELF2_x86-64.o %T/test_ELF_ExternalGlobal_x86-64.o
>>>>
>>>> +
>>>> +# Assembly obtained by compiling the following and adding checks:
>>>> +# @G = external global i8*
>>>> +#
>>>> +# define i8* @foo() {
>>>> +#    %ret = load i8** @G
>>>> +#    ret i32 %ret
>>>> +# }
>>>> +#
>>>> +
>>>> +#
>>>> +       .text
>>>> +       .file   "ELF_x64-64_PIC_relocations.ll"
>>>> +       .align  16, 0x90
>>>> +       .type   foo, at function
>>>> +foo:                                    # @foo
>>>> +# BB#0:
>>>> +       movq    G at GOTPCREL(%rip), %rax
>>>> +       movl    (%rax), %eax
>>>> +       retq
>>>> +.Ltmp0:
>>>> +       .size   foo, .Ltmp0-foo
>>>> +
>>>> +
>>>> +       .section        ".note.GNU-stack","", at progbits
>>>>
>>>> Added:
>>>> llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ExternalGlobal.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ExternalGlobal.ll?rev=234839&view=auto
>>>>
>>>> ==============================================================================
>>>> ---
>>>> llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ExternalGlobal.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ExternalGloba
>>>>
>>>> +++ l.ll Mon Apr 13 21:10:35 2015
>>>> @@ -0,0 +1,2 @@
>>>> + at F = global i8 0
>>>> + at G = global i8* @F
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>> ---------------------------------------------------------------------
>>>> Intel Israel (74) Limited
>>>>
>>>> This e-mail and any attachments may contain confidential material for
>>>> the sole use of the intended recipient(s). Any review or distribution
>>>> by others is strictly prohibited. If you are not the intended
>>>> recipient, please contact the sender and delete all copies.
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> Intel Israel (74) Limited
>>>>
>>>> This e-mail and any attachments may contain confidential material for
>>>> the sole use of the intended recipient(s). Any review or distribution
>>>> by others is strictly prohibited. If you are not the intended
>>>> recipient, please contact the sender and delete all copies.
>>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150415/c3191865/attachment.html>


More information about the llvm-commits mailing list