[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