[Lldb-commits] [lldb] r153822 - in /lldb/trunk: llvm.zip scripts/llvm.full-i386-relocations.diff scripts/llvm.i386-relocations.diff scripts/llvm.relocate-both-ways.r2.diff

Sean Callanan scallanan at apple.com
Sat Mar 31 23:35:00 PDT 2012


Author: spyffe
Date: Sun Apr  1 01:35:00 2012
New Revision: 153822

URL: http://llvm.org/viewvc/llvm-project?rev=153822&view=rev
Log:
Updated LLVM to take a comprehensive fix to the
JIT that enables paired relocations in the i386
Mach-O JIT.  This eliminates crashes in the
testsuite when running under i386.

Added:
    lldb/trunk/scripts/llvm.full-i386-relocations.diff
Removed:
    lldb/trunk/scripts/llvm.i386-relocations.diff
    lldb/trunk/scripts/llvm.relocate-both-ways.r2.diff
Modified:
    lldb/trunk/llvm.zip

Modified: lldb/trunk/llvm.zip
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/llvm.zip?rev=153822&r1=153821&r2=153822&view=diff
==============================================================================
Binary files - no diff available.

Added: lldb/trunk/scripts/llvm.full-i386-relocations.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/llvm.full-i386-relocations.diff?rev=153822&view=auto
==============================================================================
--- lldb/trunk/scripts/llvm.full-i386-relocations.diff (added)
+++ lldb/trunk/scripts/llvm.full-i386-relocations.diff Sun Apr  1 01:35:00 2012
@@ -0,0 +1,841 @@
+Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+===================================================================
+--- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp	(revision 152265)
++++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp	(working copy)
+@@ -24,7 +24,8 @@
+ bool RuntimeDyldMachO::
+ resolveRelocation(uint8_t *LocalAddress,
+                   uint64_t FinalAddress,
+-                  uint64_t Value,
++                  uint64_t FinalSource1,
++                  uint64_t FinalSource2,
+                   bool isPCRel,
+                   unsigned Type,
+                   unsigned Size,
+@@ -32,10 +33,20 @@
+   // This just dispatches to the proper target specific routine.
+   switch (CPUType) {
+   default: llvm_unreachable("Unsupported CPU type!");
++  case mach::CTM_i386:
++    return resolveI386Relocation(LocalAddress,
++                                 FinalAddress,
++                                 FinalSource1,
++                                 FinalSource2,
++                                 isPCRel,
++                                 Type,
++                                 Size,
++                                 Addend);
+   case mach::CTM_x86_64:
+     return resolveX86_64Relocation(LocalAddress,
+                                    FinalAddress,
+-                                   (uintptr_t)Value,
++                                   FinalSource1,
++                                   FinalSource2,
+                                    isPCRel,
+                                    Type,
+                                    Size,
+@@ -43,7 +54,8 @@
+   case mach::CTM_ARM:
+     return resolveARMRelocation(LocalAddress,
+                                 FinalAddress,
+-                                (uintptr_t)Value,
++                                FinalSource1,
++                                FinalSource2,
+                                 isPCRel,
+                                 Type,
+                                 Size,
+@@ -52,19 +64,52 @@
+ }
+ 
+ bool RuntimeDyldMachO::
++resolveI386Relocation(uint8_t *LocalAddress,
++                      uint64_t FinalAddress,
++                      uint64_t FinalSource1,
++                      uint64_t FinalSource2,
++                      bool isPCRel,
++                      unsigned Type,
++                      unsigned Size,
++                      int64_t Addend) {
++  int64_t ValueToWrite = Addend;
++
++  switch (Type) {
++  default:
++    llvm_unreachable("Invalid relocation type!");
++  case macho::RIT_Vanilla:
++    ValueToWrite += FinalSource1;
++    break;
++  case macho::RIT_Difference:
++  case macho::RIT_Generic_LocalDifference:
++  case macho::RIT_Generic_PreboundLazyPointer:
++    ValueToWrite += FinalSource1;
++    ValueToWrite -= FinalSource2;
++    break;
++  }
++
++  if (isPCRel)
++    ValueToWrite -= FinalAddress + 4; // see resolveX86_64Relocation
++
++  uint8_t *p = LocalAddress;
++  for (unsigned i = 0; i < Size; ++i) {
++    *p++ = (uint8_t)(ValueToWrite & 0xff);
++    ValueToWrite >>= 8;
++  }
++
++  return false;
++}
++
++bool RuntimeDyldMachO::
+ resolveX86_64Relocation(uint8_t *LocalAddress,
+                         uint64_t FinalAddress,
+-                        uint64_t Value,
++                        uint64_t FinalSource1,
++                        uint64_t FinalSource2,
+                         bool isPCRel,
+                         unsigned Type,
+                         unsigned Size,
+                         int64_t Addend) {
+-  // If the relocation is PC-relative, the value to be encoded is the
+-  // pointer difference.
+-  if (isPCRel)
+-    // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
+-    // address. Is that expected? Only for branches, perhaps?
+-    Value -= FinalAddress + 4;
++  int64_t ValueToWrite = Addend;
+ 
+   switch(Type) {
+   default:
+@@ -74,41 +119,53 @@
+   case macho::RIT_X86_64_Signed4:
+   case macho::RIT_X86_64_Signed:
+   case macho::RIT_X86_64_Unsigned:
+-  case macho::RIT_X86_64_Branch: {
+-    Value += Addend;
+-    // Mask in the target value a byte at a time (we don't have an alignment
+-    // guarantee for the target address, so this is safest).
+-    uint8_t *p = (uint8_t*)LocalAddress;
+-    for (unsigned i = 0; i < Size; ++i) {
+-      *p++ = (uint8_t)Value;
+-      Value >>= 8;
+-    }
+-    return false;
+-  }
++  case macho::RIT_X86_64_Branch:
++    ValueToWrite += FinalSource1;
++    break;
+   case macho::RIT_X86_64_GOTLoad:
+   case macho::RIT_X86_64_GOT:
+   case macho::RIT_X86_64_Subtractor:
+   case macho::RIT_X86_64_TLV:
+     return Error("Relocation type not implemented yet!");
+   }
++
++  // If the relocation is PC-relative, the value to be encoded is the
++  // pointer difference.
++  if (isPCRel)
++    // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
++    // address. Is that expected? Only for branches, perhaps?
++    ValueToWrite -= FinalAddress + 4;
++
++  // Mask in the target value a byte at a time (we don't have an alignment
++  // guarantee for the target address, so this is safest).
++  uint8_t *p = (uint8_t*)LocalAddress;
++  for (unsigned i = 0; i < Size; ++i) {
++    *p++ = (uint8_t)(ValueToWrite & 0xff);
++    ValueToWrite >>= 8;
++  }
++
++  return false;
+ }
+ 
+ bool RuntimeDyldMachO::
+ resolveARMRelocation(uint8_t *LocalAddress,
+                      uint64_t FinalAddress,
+-                     uint64_t Value,
++                     uint64_t FinalSource1,
++                     uint64_t FinalSource2,
+                      bool isPCRel,
+                      unsigned Type,
+                      unsigned Size,
+                      int64_t Addend) {
++  int64_t ValueToWrite = Addend;
++
+   // If the relocation is PC-relative, the value to be encoded is the
+   // pointer difference.
+   if (isPCRel) {
+-    Value -= FinalAddress;
++    ValueToWrite -= FinalAddress;
+     // ARM PCRel relocations have an effective-PC offset of two instructions
+     // (four bytes in Thumb mode, 8 bytes in ARM mode).
+     // FIXME: For now, assume ARM mode.
+-    Value -= 8;
++    ValueToWrite -= 8;
+   }
+ 
+   switch(Type) {
+@@ -119,8 +176,8 @@
+     // guarantee for the target address, so this is safest).
+     uint8_t *p = (uint8_t*)LocalAddress;
+     for (unsigned i = 0; i < Size; ++i) {
+-      *p++ = (uint8_t)Value;
+-      Value >>= 8;
++      *p++ = (uint8_t)(ValueToWrite & 0xff);
++      ValueToWrite >>= 8;
+     }
+     break;
+   }
+@@ -129,15 +186,15 @@
+     // 32-bit aligned, so we can do it all at once.
+     uint32_t *p = (uint32_t*)LocalAddress;
+     // The low two bits of the value are not encoded.
+-    Value >>= 2;
++    ValueToWrite >>= 2;
+     // Mask the value to 24 bits.
+-    Value &= 0xffffff;
++    ValueToWrite &= 0xffffff;
+     // FIXME: If the destination is a Thumb function (and the instruction
+     // is a non-predicated BL instruction), we need to change it to a BLX
+     // instruction instead.
+ 
+     // Insert the value into the instruction.
+-    *p = (*p & ~0xffffff) | Value;
++    *p = (*p & ~0xffffff) | ValueToWrite;
+     break;
+   }
+   case macho::RIT_ARM_ThumbBranch22Bit:
+@@ -153,6 +210,29 @@
+   return false;
+ }
+ 
++static bool
++ResolveSectionAndOffset(const MachOObject *Obj,
++                        SmallVectorImpl<unsigned> &SectionMap,
++                        const MachOObject::LoadCommandInfo *SegmentLCI,
++                        InMemoryStruct<macho::SegmentLoadCommand> &SegmentLC,
++                        uint64_t Address,
++                        unsigned &SectionID,
++                        uint64_t &Offset)
++{
++  for (unsigned SI = 0, SE = SegmentLC->NumSections; SI < SE; ++SI) {
++    InMemoryStruct<macho::Section> CandidateSection;
++    Obj->ReadSection(*SegmentLCI, SI, CandidateSection);
++    if (Address >= CandidateSection->Address &&
++        Address < CandidateSection->Address + CandidateSection->Size) {
++      SectionID = SectionMap[SI];
++      Offset = Address - CandidateSection->Address;
++      return true;
++    }
++  }
++
++  return false;
++}
++
+ bool RuntimeDyldMachO::
+ loadSegment32(const MachOObject *Obj,
+               const MachOObject::LoadCommandInfo *SegmentLCI,
+@@ -210,6 +290,7 @@
+ 
+   // Process the relocations for each section we're loading.
+   Relocations.grow(Relocations.size() + SegmentLC->NumSections);
++  RelocationSources.grow(RelocationSources.size() + SegmentLC->NumSections);
+   for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
+     InMemoryStruct<macho::Section> Sect;
+     Obj->ReadSection(*SegmentLCI, SectNum, Sect);
+@@ -218,51 +299,135 @@
+     for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
+       InMemoryStruct<macho::RelocationEntry> RE;
+       Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
+-      if (RE->Word0 & macho::RF_Scattered)
+-        return Error("NOT YET IMPLEMENTED: scattered relocations.");
+-      // Word0 of the relocation is the offset into the section where the
+-      // relocation should be applied. We need to translate that into an
+-      // offset into a function since that's our atom.
+-      uint32_t Offset = RE->Word0;
+-      bool isExtern = (RE->Word1 >> 27) & 1;
+-
+-      // FIXME: Get the relocation addend from the target address.
+-      // FIXME: VERY imporant for internal relocations.
+-
+-      // Figure out the source symbol of the relocation. If isExtern is true,
+-      // this relocation references the symbol table, otherwise it references
+-      // a section in the same object, numbered from 1 through NumSections
+-      // (SectionBases is [0, NumSections-1]).
+-      uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
+-      if (!isExtern) {
+-        assert(SourceNum > 0 && "Invalid relocation section number!");
+-        unsigned SectionID = SectionMap[SourceNum - 1];
++      if (RE->Word0 & macho::RF_Scattered) {
++        // The lower 24 bits of Word0 of the scattered relocation is the offset
++        // into the section where the relocation should be applied, i.e., the
++        // current section.
++        uint32_t OffsetInTarget = RE->Word0 & 0x00ffffff;
+         unsigned TargetID = SectionMap[SectNum];
+-        DEBUG(dbgs() << "Internal relocation at Section #"
+-                     << TargetID << " + " << Offset
+-                     << " from Section #"
+-                     << SectionID << " (Word1: "
+-                     << format("0x%x", RE->Word1) << ")\n");
+-
+-        // Store the relocation information. It will get resolved when
+-        // the section addresses are assigned.
+-        Relocations[SectionID].push_back(RelocationEntry(TargetID,
+-                                                         Offset,
+-                                                         RE->Word1,
+-                                                         0 /*Addend*/));
++        // Word1 of the scattered relocation is a file offset which needs to
++        // be resolved into Section+Offset form.  This gives the address of the
++        // source.
++        unsigned Source1ID;
++        uint64_t Source1Offset;
++        if (!ResolveSectionAndOffset(Obj,
++                                     SectionMap,
++                                     SegmentLCI,
++                                     SegmentLC,
++                                     RE->Word1,
++                                     Source1ID,
++                                     Source1Offset))
++          return Error("couldn't find scattered relocation value in sections");
++        // This relocation may have a paired relocation entry. If it does, set
++        // the source/offset information for it correctly.
++        unsigned Source2ID = SectionOffset::NoSectionID;
++        uint64_t Source2Offset = 0;
++        if (j + 1 < Sect->NumRelocationTableEntries) {
++          InMemoryStruct<macho::RelocationEntry> PairRE;
++          Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j+1, PairRE);
++          if ((PairRE->Word0 & macho::RF_Scattered) &&
++              ((PairRE->Word0 & 0x0f000000) >> 24) == macho::RIT_Pair) {
++            if (!ResolveSectionAndOffset(Obj,
++                                         SectionMap,
++                                         SegmentLCI,
++                                         SegmentLC,
++                                         PairRE->Word1,
++                                         Source2ID,
++                                         Source2Offset))
++              return Error("couldn't find scattered relocation value in sections");
++            ++j;
++          }
++        }
++        if (Source2ID == SectionOffset::NoSectionID)
++          DEBUG(dbgs() << "Scattered relocation at Section #"
++                       << TargetID << " + " << OffsetInTarget
++                       << " from Section #" << Source1ID
++                       << "+" << Source1Offset
++                       << " (Word0: "
++                       << format("0x%x", RE->Word0) << ")\n");
++        else
++          DEBUG(dbgs() << "Scattered relocation at Section #"
++                       << TargetID << " + " << OffsetInTarget
++                       << " from Section #" << Source1ID
++                       << "+" << Source1Offset
++                       << " and Section #" << Source2ID
++                       << "+" << Source2Offset
++                       << " (Word0: "
++                       << format("0x%x", RE->Word0) << ")\n");
++        uint32_t RelocationIndex = Relocations[TargetID].size();
++        // FIXME: Get the relocation addend from the target address.
++        // FIXME: VERY imporant for internal relocations.
++        RelocationEntry TranslatedRE(OffsetInTarget,
++                                     Source1ID,
++                                     Source1Offset,
++                                     Source2ID,
++                                     Source2Offset,
++                                     RE->Word1,
++                                     0 /*Addend*/);
++        Relocations[TargetID].push_back(TranslatedRE);
++        RelocationSources[Source1ID].push_back(RelocationSource(TargetID,
++                                                                RelocationIndex,
++                                                                0));
++        if (Source2ID != SectionOffset::NoSectionID)
++          RelocationSources[Source2ID].push_back(RelocationSource(TargetID,
++                                                                  RelocationIndex,
++                                                                  1));
+       } else {
+-        StringRef SourceName = SymbolNames[SourceNum];
+-
+-        // Now store the relocation information. Associate it with the source
+-        // symbol. Just add it to the unresolved list and let the general
+-        // path post-load resolve it if we know where the symbol is.
+-        UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
+-                                                                    Offset,
+-                                                                    RE->Word1,
+-                                                                 0 /*Addend*/));
+-        DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
+-              << " from '" << SourceName << "(Word1: "
+-              << format("0x%x", RE->Word1) << ")\n");
++        // Word0 of the relocation is the offset into the section where the
++        // relocation should be applied, i.e., the current section. We need
++        // to translate that into an offset into a function since that's our atom.
++        uint32_t OffsetInTarget = RE->Word0;
++        bool isExtern = (RE->Word1 >> 27) & 1;
++  
++        // FIXME: Get the relocation addend from the target address.
++        // FIXME: VERY imporant for internal relocations.
++  
++        // Figure out the source symbol of the relocation. If isExtern is true,
++        // this relocation references the symbol table, otherwise it references
++        // a section in the same object, numbered from 1 through NumSections
++        // (SectionBases is [0, NumSections-1]).
++        uint32_t SourceNum_OneBased = RE->Word1 & 0xffffff; // 24-bit value
++        if (!isExtern) {
++          assert(SourceNum_OneBased > 0 && "Invalid relocation section number!");
++          unsigned SourceID = SectionMap[SourceNum_OneBased - 1];
++          unsigned TargetID = SectionMap[SectNum];
++          DEBUG(dbgs() << "Internal relocation at Section #"
++                       << TargetID << " + " << OffsetInTarget
++                       << " from Section #"
++                       << SourceID << " (Word1: "
++                       << format("0x%x", RE->Word1) << ")\n");
++  
++          // Store the relocation information. It will get resolved when
++          // the section addresses are assigned.
++          uint32_t RelocationIndex = Relocations[TargetID].size();
++          Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
++                                                          SourceID,
++                                                          SectionOffset::NoSectionID,
++                                                          RE->Word1,
++                                                          0 /*Addend*/));
++          RelocationSources[SourceID].push_back(RelocationSource(TargetID,
++                                                                 RelocationIndex,
++                                                                 0));
++        } else {
++          StringRef SourceName = SymbolNames[SourceNum_OneBased];
++  
++          // Now store the relocation information. Associate it with the source
++          // symbol. Just add it to the unresolved list and let the general
++          // path post-load resolve it if we know where the symbol is.
++          unsigned TargetID = SectionMap[SectNum];
++          uint32_t RelocationIndex = Relocations[TargetID].size();
++          Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
++                                                          SectionOffset::UnresolvedSourceID,
++                                                          SectionOffset::NoSectionID,
++                                                          RE->Word1,
++                                                          0 /*Addend*/));
++          UnresolvedRelocations[SourceName].push_back(RelocationSource(TargetID,
++                                                                       RelocationIndex,
++                                                                       0));
++          DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << OffsetInTarget
++                << " from '" << SourceName << "' (Word1: "
++                << format("0x%x", RE->Word1) << ")\n");
++        }
+       }
+     }
+   }
+@@ -332,6 +497,7 @@
+ 
+   // Process the relocations for each section we're loading.
+   Relocations.grow(Relocations.size() + Segment64LC->NumSections);
++  RelocationSources.grow(RelocationSources.size() + Segment64LC->NumSections);
+   for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
+     InMemoryStruct<macho::Section64> Sect;
+     Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
+@@ -341,11 +507,11 @@
+       InMemoryStruct<macho::RelocationEntry> RE;
+       Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
+       if (RE->Word0 & macho::RF_Scattered)
+-        return Error("NOT YET IMPLEMENTED: scattered relocations.");
++        return Error("scattered relocations don't exist on 64-bit platforms");
+       // Word0 of the relocation is the offset into the section where the
+       // relocation should be applied. We need to translate that into an
+       // offset into a function since that's our atom.
+-      uint32_t Offset = RE->Word0;
++      uint32_t OffsetInTarget = RE->Word0;
+       bool isExtern = (RE->Word1 >> 27) & 1;
+ 
+       // FIXME: Get the relocation addend from the target address.
+@@ -355,34 +521,45 @@
+       // this relocation references the symbol table, otherwise it references
+       // a section in the same object, numbered from 1 through NumSections
+       // (SectionBases is [0, NumSections-1]).
+-      uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
++      uint32_t SourceNum_OneBased = RE->Word1 & 0xffffff; // 24-bit value
+       if (!isExtern) {
+-        assert(SourceNum > 0 && "Invalid relocation section number!");
+-        unsigned SectionID = SectionMap[SourceNum - 1];
++        assert(SourceNum_OneBased > 0 && "Invalid relocation section number!");
++        unsigned SourceID = SectionMap[SourceNum_OneBased - 1];
+         unsigned TargetID = SectionMap[SectNum];
+         DEBUG(dbgs() << "Internal relocation at Section #"
+-                     << TargetID << " + " << Offset
++                     << TargetID << " + " << OffsetInTarget
+                      << " from Section #"
+-                     << SectionID << " (Word1: "
++                     << SourceID << " (Word1: "
+                      << format("0x%x", RE->Word1) << ")\n");
+ 
+         // Store the relocation information. It will get resolved when
+         // the section addresses are assigned.
+-        Relocations[SectionID].push_back(RelocationEntry(TargetID,
+-                                                         Offset,
+-                                                         RE->Word1,
+-                                                         0 /*Addend*/));
++        uint32_t RelocationIndex = Relocations[TargetID].size();
++        Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
++                                                        SourceID,
++                                                        SectionOffset::NoSectionID,
++                                                        RE->Word1,
++                                                        0 /*Addend*/));
++        RelocationSources[SourceID].push_back(RelocationSource(TargetID,
++                                                               RelocationIndex,
++                                                               0));
+       } else {
+-        StringRef SourceName = SymbolNames[SourceNum];
++        StringRef SourceName = SymbolNames[SourceNum_OneBased];
+ 
+         // Now store the relocation information. Associate it with the source
+         // symbol. Just add it to the unresolved list and let the general
+         // path post-load resolve it if we know where the symbol is.
+-        UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
+-                                                                    Offset,
+-                                                                    RE->Word1,
+-                                                                 0 /*Addend*/));
+-        DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
++        unsigned TargetID = SectionMap[SectNum];
++        uint32_t RelocationIndex = Relocations[TargetID].size();
++        Relocations[TargetID].push_back(RelocationEntry(OffsetInTarget,
++                                                        SectionOffset::UnresolvedSourceID,
++                                                        SectionOffset::NoSectionID,
++                                                        RE->Word1,
++                                                        0 /*Addend*/));
++        UnresolvedRelocations[SourceName].push_back(RelocationSource(TargetID,
++                                                                     RelocationIndex,
++                                                                     0));
++        DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << OffsetInTarget
+               << " from '" << SourceName << "(Word1: "
+               << format("0x%x", RE->Word1) << ")\n");
+       }
+@@ -468,18 +645,22 @@
+   if (Loc == SymbolTable.end())
+     return;
+ 
+-  RelocationList &Relocs = UnresolvedRelocations[Name];
++  RelocationSourceList &SourcesForSymbol = UnresolvedRelocations[Name];
+   DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
+-  for (int i = 0, e = Relocs.size(); i != e; ++i) {
+-    // Change the relocation to be section relative rather than symbol
+-    // relative and move it to the resolved relocation list.
+-    RelocationEntry Entry = Relocs[i];
+-    Entry.Addend += Loc->second.second;
+-    Relocations[Loc->second.first].push_back(Entry);
++  for (int i = 0, e = SourcesForSymbol.size(); i != e; ++i) {
++    // Find the relocation entry corresponding to this source and fill
++    // in its source information with the resolved information from this
++    // symbol.
++    RelocationSource &Source = SourcesForSymbol[i];
++    RelocationEntry &Entry = Relocations[Source.SectionID][Source.Index];
++    Entry.Sources[Source.SourceIdx].Offset = Loc->second.second;
++    Entry.Sources[Source.SourceIdx].ID = Loc->second.first;
++    // Now create a relocation source in the pointed-to section.
++    RelocationSources[Loc->second.first].push_back(Source);
+   }
+   // FIXME: Keep a worklist of the relocations we've added so that we can
+   // resolve more selectively later.
+-  Relocs.clear();
++  SourcesForSymbol.clear();
+ }
+ 
+ bool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) {
+@@ -575,6 +756,56 @@
+   return false;
+ }
+ 
++bool RuntimeDyldMachO::resolveRelocationEntry(unsigned SectionID,
++                                              RelocationEntry &RE)
++{
++  uint8_t *Target = (uint8_t*)Sections[SectionID].base() + RE.Offset;
++  uint64_t FinalTarget = SectionLoadAddress[SectionID] + RE.Offset;
++
++  uint64_t FinalSource1 = 0;
++  uint64_t FinalSource2 = 0;
++
++  if (RE.Sources[0].ID == SectionOffset::UnresolvedSourceID ||
++      RE.Sources[1].ID == SectionOffset::UnresolvedSourceID)
++    return false;
++
++  FinalSource1 = SectionLoadAddress[RE.Sources[0].ID] + RE.Sources[0].Offset;
++  if (RE.Sources[1].ID != SectionOffset::NoSectionID)
++    FinalSource2 = SectionLoadAddress[RE.Sources[1].ID] + RE.Sources[1].Offset;
++
++  bool isPCRel = RE.isPCRel();
++  unsigned Type = RE.type();
++  unsigned Size = RE.length();
++
++  if (RE.Sources[1].ID == SectionOffset::NoSectionID)
++    DEBUG(dbgs() << "Resolving relocation at Section #" << SectionID
++          << " + " << RE.Offset << " (" << format("%p", Target) << ")"
++          << " from Section #" << RE.Sources[0].ID << "+" << RE.Sources[0].Offset
++          << " (" << format("0x%llx", FinalSource1) << ")"
++          << " (" << (isPCRel ? "pcrel" : "absolute")
++          << ", type: " << Type << ", Size: " << Size << ", Addend: "
++          << RE.Addend << ").\n");
++  else
++    DEBUG(dbgs() << "Resolving relocation at Section #" << SectionID
++          << " + " << RE.Offset << " (" << format("%p", Target) << ")"
++          << " from Section #" << RE.Sources[0].ID << "+" << RE.Sources[0].Offset
++          << " (" << format("0x%llx", FinalSource1) << ")"
++          << " and Section #" << RE.Sources[1].ID << "+" << RE.Sources[1].Offset
++          << " (" << format("0x%llx", FinalSource2) << ")"
++          << " (" << (isPCRel ? "pcrel" : "absolute")
++          << ", type: " << Type << ", Size: " << Size << ", Addend: "
++          << RE.Addend << ").\n");
++
++  return resolveRelocation(Target,
++                           FinalTarget,
++                           FinalSource1,
++                           FinalSource2,
++                           isPCRel,
++                           Type,
++                           Size,
++                           RE.Addend);
++}
++
+ // Assign an address to a symbol name and resolve all the relocations
+ // associated with it.
+ void RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID,
+@@ -590,30 +821,17 @@
+ 
+   SectionLoadAddress[SectionID] = Addr;
+ 
+-  RelocationList &Relocs = Relocations[SectionID];
+-  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
+-    RelocationEntry &RE = Relocs[i];
+-    uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
+-    uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
+-    bool isPCRel = (RE.Data >> 24) & 1;
+-    unsigned Type = (RE.Data >> 28) & 0xf;
+-    unsigned Size = 1 << ((RE.Data >> 25) & 3);
+-
+-    DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
+-          << " + " << RE.Offset << " (" << format("%p", Target) << ")"
+-          << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
+-          << "(" << (isPCRel ? "pcrel" : "absolute")
+-          << ", type: " << Type << ", Size: " << Size << ", Addend: "
+-          << RE.Addend << ").\n");
+-
+-    resolveRelocation(Target,
+-                      FinalTarget,
+-                      Addr,
+-                      isPCRel,
+-                      Type,
+-                      Size,
+-                      RE.Addend);
++  RelocationList &RelocsForSection = Relocations[SectionID];
++  for (unsigned i = 0, e = RelocsForSection.size(); i != e; ++i) {
++    RelocationEntry &RE = RelocsForSection[i];
++    resolveRelocationEntry(SectionID, RE);
+   }
++  RelocationSourceList &SourcesForSection = RelocationSources[SectionID];
++  for (unsigned i = 0, e = SourcesForSection.size(); i != e; ++i) {
++    RelocationSource &R = SourcesForSection[i];
++    RelocationEntry &RE = Relocations[R.SectionID][R.Index];
++    resolveRelocationEntry(R.SectionID, RE);
++  }
+ }
+ 
+ bool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) {
+Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+===================================================================
+--- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h	(revision 152265)
++++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h	(working copy)
+@@ -26,48 +26,183 @@
+ namespace llvm {
+ class RuntimeDyldMachO : public RuntimeDyldImpl {
+ 
+-  // For each symbol, keep a list of relocations based on it. Anytime
+-  // its address is reassigned (the JIT re-compiled the function, e.g.),
+-  // the relocations get re-resolved.
+-  // The symbol (or section) the relocation is sourced from is the Key
+-  // in the relocation list where it's stored.
++  // For each section, keep a list of relocatable pieces of data that
++  // reside in it.  If the section moves, or the sections whose
++  // locations the data depends on move, re-resolve the relocations
++  // based on that movement.
++  //
++  // RelocationEntry structures correspond to one or two Mach-O
++  // relocation_info or scattered_relocation_info structures --
++  // usually one, but two iff the original has a paired structure
++  // following it.
++  //
++  // To facilitate updating a relocation when its sources move, we
++  // also keep RelocationSource structures associated with the sections
++  // whose location the data depends on.
++
++  // FIXME: Use SymbolLoc for this instead.  Where should the enum live?
++  struct SectionOffset {
++    uint64_t    Offset;     // Offset of the location into its section.
++    unsigned    ID;         // The section the location is contained in.
++
++    enum {
++      NoSectionID        = 0xffff0000,
++      UnresolvedSourceID = 0xffffffff
++    };
++  };
++
+   struct RelocationEntry {
+-    unsigned    SectionID;  // Section the relocation is contained in.
+-    uint64_t    Offset;     // Offset into the section for the relocation.
+-    uint32_t    Data;       // Second word of the raw macho relocation entry.
+-    int64_t     Addend;     // Addend encoded in the instruction itself, if any,
+-                            // plus the offset into the source section for
+-                            // the symbol once the relocation is resolvable.
++    SectionOffset Sources[2]; // The section/offset pairs this relocation
++                              // refers to.
++                              // If the original Mach-O relocation entries used
++                              // relocation_info, this data is computed from
++                              // r_symbolnum and the offsets are locked to 0.
++                              // (The only offset is determined by the addend.)
++                              // If the original Mach-O relocation entries used
++                              // scattered_relocation_info, this data, including
++                              // offsets, is computed by looking r_value up in
++                              // the section table.
+ 
+-    RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
+-      : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
++    uint64_t      Offset;     // The offset of the data to be relocated.
++                              // We don't use a SectionOffset because this
++                              // RelocationEntry is already associated with the
++                              // proper Section.
++
++    int64_t       Addend;     // Addend encoded in the instruction itself, if any,
++                              // plus the offset into the source section for
++                              // the symbol once the relocation is resolvable.
++
++    uint32_t      Data;       // If the original Mach-O relocation entry was a
++                              // relocation_info, the bitfield { r_symbolnum,
++                              // r_pcrel, r_length, r_extern, r_type }.
++                              // If the original Mach-O relocation entry was a
++                              // scattered_relocation_info, the bitfield
++                              // { r_address, r_type, r_length, r_pcrel,
++                              // r_scattered }.
++
++    bool          Scattered;  // True iff this relocation is scattered.
++
++    bool isPCRel()
++    {
++      if (Scattered)
++        return (Data & 0x40000000) >> 30;
++      else
++        return (Data & 0x01000000) >> 24;
++    }
++
++    uint8_t type()
++    {
++      if (Scattered)
++        return (Data & 0x0f000000) >> 24;
++      else
++        return (Data & 0xf0000000) >> 28;
++    }
++
++    // Returns the decoded version of the length field
++    uint8_t length()
++    {
++      if (Scattered)
++        return 1 << ((Data & 0x30000000) >> 28);
++      else
++        return 1 << ((Data & 0x0e000000) >> 25);
++    }
++
++    // Used with an ordinary relocation entry, where the source_offsets are not
++    // known yet.
++    RelocationEntry(uint64_t offset,      // See the Offset field.
++                    unsigned source_id0,  // The section ID for the first source.
++                    unsigned source_id1,  // The section ID for the second source.
++                    uint32_t data,        // See the Data field.
++                    int64_t addend)       // See the Addend field.
++      : Offset(offset),
++        Addend(addend),
++        Data(data),
++        Scattered(false) {
++      Sources[0].ID = source_id0;
++      Sources[0].Offset = 0;
++      Sources[1].ID = source_id1;
++      Sources[1].Offset = 0;
++    }
++  
++    // Used with a scattered relocation entry, where the source_offsets can be
++    // derived from the value.
++    RelocationEntry(uint64_t offset,      // See the Offset field.
++                    unsigned source_id0,  // The section ID for the first source.
++                    uint64_t source_off0, // The offset for the first source.
++                    unsigned source_id1,  // The section ID for the second source.
++                    uint64_t source_off1, // The offset for the second source.
++                    uint32_t data,        // See the Data field.
++                    int64_t addend)       // See the Addend field.
++      : Offset(offset),
++        Addend(addend),
++        Data(data), 
++        Scattered(true) {
++      Sources[0].ID = source_id0;
++      Sources[0].Offset = source_off0;
++      Sources[1].ID = source_id1;
++      Sources[1].Offset = source_off1;
++    }
+   };
+   typedef SmallVector<RelocationEntry, 4> RelocationList;
+-  // Relocations to sections already loaded. Indexed by SectionID which is the
+-  // source of the address. The target where the address will be writen is
+-  // SectionID/Offset in the relocation itself.
++
++  // For each section, keep a list of sources that are used by relocations in
++  // other sections.  Whenever a relocation gets created, create one or two
++  // corresponding relocation sources.  Whenever relocations are re-resolved
++  // for a section, also re-resolve the relocations corresponding to that
++  // section's relocation targets.
++  struct RelocationSource {
++    unsigned    SectionID;      // Section whose RelocationList contains the relocation.
++    uint32_t    Index : 24;     // Index of the RelocatonEntry in that RelocationList.
++    uint8_t     SourceIdx : 1;  // Index of this source in the RelocationEntry's Sources.
++
++    RelocationSource(unsigned id,
++                     uint32_t index,
++                     uint8_t source_idx)
++      : SectionID(id),
++        Index(index),
++        SourceIdx(source_idx) {}
++  };
++  typedef SmallVector<RelocationSource, 4> RelocationSourceList;
++
++  // Relocations which refer to already-loaded section. Indexed by SectionID
++  // which is the section containing the relocatable data.
+   IndexedMap<RelocationList> Relocations;
++  // Targets corresponding to Relocations.
++  IndexedMap<RelocationSourceList> RelocationSources;
+   // Relocations to symbols that are not yet resolved. Must be external
+   // relocations by definition. Indexed by symbol name.
+-  StringMap<RelocationList> UnresolvedRelocations;
++  StringMap<RelocationSourceList> UnresolvedRelocations;
+ 
++  bool resolveRelocationEntry(unsigned SectionID,
++                              RelocationEntry &RE);
+   bool resolveRelocation(uint8_t *LocalAddress,
+                          uint64_t FinalAddress,
+-                         uint64_t Value,
++                         uint64_t FinalSource1,
++                         uint64_t FinalSource2,
+                          bool isPCRel,
+                          unsigned Type,
+                          unsigned Size,
+                          int64_t Addend);
++  bool resolveI386Relocation(uint8_t *LocalAddress,
++                             uint64_t FinalAddress,
++                             uint64_t FinalSource1,
++                             uint64_t FinalSource2,
++                             bool isPCRel,
++                             unsigned Type,
++                             unsigned Size,
++                             int64_t Addend);
+   bool resolveX86_64Relocation(uint8_t *LocalAddress,
+                                uint64_t FinalAddress,
+-                               uint64_t Value,
++                               uint64_t FinalSource1,
++                               uint64_t FinalSource2,
+                                bool isPCRel,
+                                unsigned Type,
+                                unsigned Size,
+                                int64_t Addend);
+   bool resolveARMRelocation(uint8_t *LocalAddress,
+                             uint64_t FinalAddress,
+-                            uint64_t Value,
++                            uint64_t FinalSource1,
++                            uint64_t FinalSource2,
+                             bool isPCRel,
+                             unsigned Type,
+                             unsigned Size,

Removed: lldb/trunk/scripts/llvm.i386-relocations.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/llvm.i386-relocations.diff?rev=153821&view=auto
==============================================================================
--- lldb/trunk/scripts/llvm.i386-relocations.diff (original)
+++ lldb/trunk/scripts/llvm.i386-relocations.diff (removed)
@@ -1,73 +0,0 @@
-Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
-===================================================================
---- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp	(revision 153361)
-+++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp	(working copy)
-@@ -32,6 +32,14 @@
-   // This just dispatches to the proper target specific routine.
-   switch (CPUType) {
-   default: llvm_unreachable("Unsupported CPU type!");
-+  case mach::CTM_i386:
-+    return resolveI386Relocation(LocalAddress,
-+                                 FinalAddress,
-+                                 (uintptr_t)Value,
-+                                 isPCRel,
-+                                 Type,
-+                                 Size,
-+                                 Addend);
-   case mach::CTM_x86_64:
-     return resolveX86_64Relocation(LocalAddress,
-                                    FinalAddress,
-@@ -52,6 +60,35 @@
- }
- 
- bool RuntimeDyldMachO::
-+resolveI386Relocation(uint8_t *LocalAddress,
-+                      uint64_t FinalAddress,
-+                      uint64_t Value,
-+                      bool isPCRel,
-+                      unsigned Type,
-+                      unsigned Size,
-+                      int64_t Addend) {
-+  if (isPCRel)
-+    Value -= FinalAddress + 4; // see resolveX86_64Relocation
-+
-+  switch (Type) {
-+  default:
-+    llvm_unreachable("Invalid relocation type!");
-+  case macho::RIT_Vanilla: {
-+    uint8_t *p = LocalAddress;
-+    uint64_t ValueToWrite = Value + Addend;
-+    for (unsigned i = 0; i < Size; ++i) {
-+      *p++ = (uint8_t)(ValueToWrite & 0xff);
-+      ValueToWrite >>= 8;
-+    }
-+  }
-+  case macho::RIT_Difference:
-+  case macho::RIT_Generic_LocalDifference:
-+  case macho::RIT_Generic_PreboundLazyPointer:
-+    return Error("Relocation type not implemented yet!");
-+  }
-+}
-+
-+bool RuntimeDyldMachO::
- resolveX86_64Relocation(uint8_t *LocalAddress,
-                         uint64_t FinalAddress,
-                         uint64_t Value,
-Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
-===================================================================
---- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h	(revision 153361)
-+++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h	(working copy)
-@@ -74,6 +74,13 @@
-                          unsigned Type,
-                          unsigned Size,
-                          int64_t Addend);
-+  bool resolveI386Relocation(uint8_t *LocalAddress,
-+                             uint64_t FinalAddress,
-+                             uint64_t Value,
-+                             bool isPCRel,
-+                             unsigned Type,
-+                             unsigned Size,
-+                             int64_t Addend);
-   bool resolveX86_64Relocation(uint8_t *LocalAddress,
-                                uint64_t FinalAddress,
-                                uint64_t Value,

Removed: lldb/trunk/scripts/llvm.relocate-both-ways.r2.diff
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/llvm.relocate-both-ways.r2.diff?rev=153821&view=auto
==============================================================================
--- lldb/trunk/scripts/llvm.relocate-both-ways.r2.diff (original)
+++ lldb/trunk/scripts/llvm.relocate-both-ways.r2.diff (removed)
@@ -1,119 +0,0 @@
-Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
-===================================================================
---- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp	(revision 152265)
-+++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp	(working copy)
-@@ -210,6 +210,7 @@
- 
-   // Process the relocations for each section we're loading.
-   Relocations.grow(Relocations.size() + SegmentLC->NumSections);
-+  Referrers.grow(Referrers.size() + SegmentLC->NumSections);
-   for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
-     InMemoryStruct<macho::Section> Sect;
-     Obj->ReadSection(*SegmentLCI, SectNum, Sect);
-@@ -246,10 +247,12 @@
- 
-         // Store the relocation information. It will get resolved when
-         // the section addresses are assigned.
-+        uint32_t RelocationIndex = Relocations[SectionID].size();
-         Relocations[SectionID].push_back(RelocationEntry(TargetID,
-                                                          Offset,
-                                                          RE->Word1,
-                                                          0 /*Addend*/));
-+        Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
-       } else {
-         StringRef SourceName = SymbolNames[SourceNum];
- 
-@@ -332,6 +335,7 @@
- 
-   // Process the relocations for each section we're loading.
-   Relocations.grow(Relocations.size() + Segment64LC->NumSections);
-+  Referrers.grow(Referrers.size() + Segment64LC->NumSections);
-   for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
-     InMemoryStruct<macho::Section64> Sect;
-     Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
-@@ -368,10 +372,12 @@
- 
-         // Store the relocation information. It will get resolved when
-         // the section addresses are assigned.
-+        uint32_t RelocationIndex = Relocations[SectionID].size();
-         Relocations[SectionID].push_back(RelocationEntry(TargetID,
-                                                          Offset,
-                                                          RE->Word1,
-                                                          0 /*Addend*/));
-+        Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
-       } else {
-         StringRef SourceName = SymbolNames[SourceNum];
- 
-@@ -475,7 +481,9 @@
-     // relative and move it to the resolved relocation list.
-     RelocationEntry Entry = Relocs[i];
-     Entry.Addend += Loc->second.second;
-+    uint32_t RelocationIndex = Relocations[Loc->second.first].size();
-     Relocations[Loc->second.first].push_back(Entry);
-+    Referrers[Entry.SectionID].push_back(Referrer(Loc->second.first, RelocationIndex));
-   }
-   // FIXME: Keep a worklist of the relocations we've added so that we can
-   // resolve more selectively later.
-@@ -614,6 +622,31 @@
-                       Size,
-                       RE.Addend);
-   }
-+  ReferrerList &Refers = Referrers[SectionID];
-+  for (unsigned i = 0, e = Refers.size(); i != e; ++i) {
-+    Referrer &R = Refers[i];
-+    RelocationEntry &RE = Relocations[R.SectionID][R.Index];
-+    uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
-+    uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
-+    bool isPCRel = (RE.Data >> 24) & 1;
-+    unsigned Type = (RE.Data >> 28) & 0xf;
-+    unsigned Size = 1 << ((RE.Data >> 25) & 3);
-+
-+    DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
-+          << " + " << RE.Offset << " (" << format("%p", Target) << ")"
-+          << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
-+          << "(" << (isPCRel ? "pcrel" : "absolute")
-+          << ", type: " << Type << ", Size: " << Size << ", Addend: "
-+          << RE.Addend << ").\n");
-+
-+    resolveRelocation(Target,
-+                      FinalTarget,
-+                      Addr,
-+                      isPCRel,
-+                      Type,
-+                      Size,
-+                      RE.Addend);
-+  }
- }
- 
- bool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) {
-Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
-===================================================================
---- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h	(revision 152265)
-+++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h	(working copy)
-@@ -43,10 +43,26 @@
-       : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
-   };
-   typedef SmallVector<RelocationEntry, 4> RelocationList;
-+
-+  // For each section, keep a list of referrers in that section that are clients
-+  // of relocations in other sections.  Whenever a relocation gets created,
-+  // create a corresponding referrer.  Whenever relocations are re-resolved,
-+  // re-resolve the referrers' relocations as well.
-+  struct Referrer {
-+    unsigned    SectionID;  // Section whose RelocationList contains the relocation.
-+    uint32_t    Index;      // Index of the RelocatonEntry in that RelocationList.
-+
-+    Referrer(unsigned id, uint32_t index)
-+      : SectionID(id), Index(index) {}
-+  };
-+  typedef SmallVector<Referrer, 4> ReferrerList;
-+
-   // Relocations to sections already loaded. Indexed by SectionID which is the
-   // source of the address. The target where the address will be writen is
-   // SectionID/Offset in the relocation itself.
-   IndexedMap<RelocationList> Relocations;
-+  // Referrers corresponding to Relocations.
-+  IndexedMap<ReferrerList> Referrers;
-   // Relocations to symbols that are not yet resolved. Must be external
-   // relocations by definition. Indexed by symbol name.
-   StringMap<RelocationList> UnresolvedRelocations;





More information about the lldb-commits mailing list