[llvm] r234839 - [RuntimeDyldELF] Improve GOT support

Keno Fischer kfischer at college.harvard.edu
Wed Apr 15 13:14:28 PDT 2015


My apologies. I didn't quite know what to do here as it's not actually the
commit that's causing the failure, just that we didn't have any tests for
this particular relocation previously. If we just want to make the bots
green, can we xfail that test for MSVC only (also what happens if we xfail
for all of windows, will the mingw bots complain because it actually
passes)? Also, is there any way to run the bots on a proposed phabricator
patch? That way we could have seen this issue before merging it.

On Wed, Apr 15, 2015 at 9:59 AM, Aaron Ballman <aaron at aaronballman.com>
wrote:

> 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
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150415/eba24a26/attachment.html>


More information about the llvm-commits mailing list