summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2014-05-22 22:30:13 +0000
committerLang Hames <lhames@gmail.com>2014-05-22 22:30:13 +0000
commit8f33e4c5e430764ffd95d4d0cf86ef8816e745b6 (patch)
treefe057bd07830381b8dbb65edaeebdb46ece06a76 /lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
parentff93350aa69cc7fa4ade346e550eef51fff46ceb (diff)
downloadllvm-8f33e4c5e430764ffd95d4d0cf86ef8816e745b6.tar.gz
llvm-8f33e4c5e430764ffd95d4d0cf86ef8816e745b6.tar.bz2
llvm-8f33e4c5e430764ffd95d4d0cf86ef8816e745b6.tar.xz
[RuntimeDyld] Teach RuntimeDyldMachO how to handle scattered VANILLA relocs on
i386. This fixes two more MCJIT regression tests on i386: ExecutionEngine/MCJIT/2003-05-06-LivenessClobber.ll ExecutionEngine/MCJIT/2013-04-04-RelocAddend.ll The implementation of processScatteredVANILLA is tasteless (*ba-dum-ching*), but I'm working on a substantial tidy-up of RuntimeDyldMachO that should improve things. This patch also fixes a type-o in RuntimeDyldMachO::processSECTDIFFRelocation, and teaches that method to skip over the PAIR reloc following the SECTDIFF. <rdar://problem/16961886> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209478 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp64
1 files changed, 55 insertions, 9 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 30529808d0..a70b03d95c 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -460,7 +460,7 @@ relocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
section_iterator SBI = getSectionByAddress(*MachO, AddrB);
- assert(SBI != MachO->section_end() && "Can't find seciton for address B");
+ assert(SBI != MachO->section_end() && "Can't find section for address B");
uint64_t SectionBBase;
SBI->getAddress(SectionBBase);
uint64_t SectionBOffset = AddrB - SectionBBase;
@@ -483,7 +483,48 @@ relocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
addRelocationForSection(R, SectionAID);
addRelocationForSection(R, SectionBID);
- return RelI;
+ return ++RelI;
+}
+
+relocation_iterator RuntimeDyldMachO::processI386ScatteredVANILLA(
+ unsigned SectionID,
+ relocation_iterator RelI,
+ ObjectImage &Obj,
+ ObjSectionToIDMap &ObjSectionToID) {
+ const MachOObjectFile *MachO =
+ static_cast<const MachOObjectFile*>(Obj.getObjectFile());
+ MachO::any_relocation_info RE =
+ MachO->getRelocation(RelI->getRawDataRefImpl());
+
+ SectionEntry &Section = Sections[SectionID];
+ uint32_t RelocType = MachO->getAnyRelocationType(RE);
+ bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
+ unsigned Size = MachO->getAnyRelocationLength(RE);
+ uint64_t Offset;
+ RelI->getOffset(Offset);
+ uint8_t *LocalAddress = Section.Address + Offset;
+ unsigned NumBytes = 1 << Size;
+ int64_t Addend = 0;
+ memcpy(&Addend, LocalAddress, NumBytes);
+
+ unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE);
+ section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr);
+ assert(TargetSI != MachO->section_end() && "Can't find section for symbol");
+ uint64_t SectionBaseAddr;
+ TargetSI->getAddress(SectionBaseAddr);
+ SectionRef TargetSection = *TargetSI;
+ bool IsCode;
+ TargetSection.isText(IsCode);
+ uint32_t TargetSectionID = findOrEmitSection(Obj, TargetSection, IsCode,
+ ObjSectionToID);
+
+ Addend -= SectionBaseAddr;
+ RelocationEntry R(SectionID, Offset, RelocType, Addend,
+ IsPCRel, Size);
+
+ addRelocationForSection(R, TargetSectionID);
+
+ return ++RelI;
}
relocation_iterator RuntimeDyldMachO::processRelocationRef(
@@ -498,17 +539,22 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
uint32_t RelType = MachO->getAnyRelocationType(RE);
// FIXME: Properly handle scattered relocations.
- // For now, optimistically skip these: they can often be ignored, as
- // the static linker will already have applied the relocation, and it
- // only needs to be reapplied if symbols move relative to one another.
- // Note: This will fail horribly where the relocations *do* need to be
- // applied, but that was already the case.
+ // Special case the couple of scattered relocations that we know how
+ // to handle: SECTDIFF relocations, and scattered VANILLA relocations
+ // on I386.
+ // For all other scattered relocations, just bail out and hope for the
+ // best, since the offsets computed by scattered relocations have often
+ // been optimisticaly filled in by the compiler. This will fail
+ // horribly where the relocations *do* need to be applied, but that was
+ // already the case.
if (MachO->isRelocationScattered(RE)) {
if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID);
-
- return ++RelI;
+ else if (Arch == Triple::x86 && RelType == MachO::GENERIC_RELOC_VANILLA)
+ return processI386ScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID);
+ else
+ return ++RelI;
}
RelocationValueRef Value;