forked from OSchip/llvm-project
120 lines
5.5 KiB
Diff
120 lines
5.5 KiB
Diff
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;
|