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
This commit is contained in:
Sean Callanan 2012-03-21 16:42:08 +00:00
parent cc4ab9d9c0
commit 8ce585f8f1
1 changed files with 119 additions and 0 deletions

View File

@ -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<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;