From 8ce585f8f1147c67f18168baabf02f328f19059b Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Wed, 21 Mar 2012 16:42:08 +0000 Subject: [PATCH] Added a local patch to reflect an LLVM fix for relocations (LLVM revision 153147). Now when we report section locations in the target process, LLVM will apply both those relocations whose targets are in that section and those relocations which reside in that section and point to other sections. llvm-svn: 153199 --- lldb/scripts/llvm.relocate-both-ways.r2.diff | 119 +++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 lldb/scripts/llvm.relocate-both-ways.r2.diff diff --git a/lldb/scripts/llvm.relocate-both-ways.r2.diff b/lldb/scripts/llvm.relocate-both-ways.r2.diff new file mode 100644 index 000000000000..7f41768f65e7 --- /dev/null +++ b/lldb/scripts/llvm.relocate-both-ways.r2.diff @@ -0,0 +1,119 @@ +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 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 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 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 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 Relocations; ++ // Referrers corresponding to Relocations. ++ IndexedMap Referrers; + // Relocations to symbols that are not yet resolved. Must be external + // relocations by definition. Indexed by symbol name. + StringMap UnresolvedRelocations;