[llvm] r234839 - [RuntimeDyldELF] Improve GOT support

Aaron Ballman aaron at aaronballman.com
Wed Apr 15 06:59:45 PDT 2015


It would be good if we could revert this back to green while
investigating, as we have bots that have been red for over 24 hours
now:

http://bb.pgr.jp/builders/msbuild-llvmclang-x64-msc18-DA/builds/152

~Aaron

On Wed, Apr 15, 2015 at 5:40 AM, Keno Fischer
<kfischer at college.harvard.edu> wrote:
> 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.
>>>>
>>>>
>>>
>>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list