diff options
author | Lang Hames <lhames@gmail.com> | 2014-05-22 22:30:13 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2014-05-22 22:30:13 +0000 |
commit | 7f9fc2b339fa26b279135007a6b5568624c5a2ef (patch) | |
tree | 5477971b471c4e82f64ff92292fb27cf2daa40bd /llvm/lib/ExecutionEngine | |
parent | 0a0d6b4bb123e833df89cbb287e467f811324882 (diff) | |
download | bcm5719-llvm-7f9fc2b339fa26b279135007a6b5568624c5a2ef.tar.gz bcm5719-llvm-7f9fc2b339fa26b279135007a6b5568624c5a2ef.zip |
[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>
llvm-svn: 209478
Diffstat (limited to 'llvm/lib/ExecutionEngine')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp | 64 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h | 6 |
2 files changed, 61 insertions, 9 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 30529808d0d..a70b03d95cf 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/llvm/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; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 138c59b95ce..6911f2f07aa 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -71,6 +71,12 @@ private: ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID); + relocation_iterator processI386ScatteredVANILLA( + unsigned SectionID, + relocation_iterator RelI, + ObjectImage &ObjImg, + ObjSectionToIDMap &ObjSectionToID); + struct EHFrameRelatedSections { EHFrameRelatedSections() : EHFrameSID(RTDYLD_INVALID_SECTION_ID), |