[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
This commit is contained in:
Lang Hames 2014-05-22 22:30:13 +00:00
parent 0a0d6b4bb1
commit 7f9fc2b339
2 changed files with 61 additions and 9 deletions

View File

@ -460,7 +460,7 @@ relocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
uint32_t AddrB = MachO->getScatteredRelocationValue(RE2); uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
section_iterator SBI = getSectionByAddress(*MachO, AddrB); 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; uint64_t SectionBBase;
SBI->getAddress(SectionBBase); SBI->getAddress(SectionBBase);
uint64_t SectionBOffset = AddrB - SectionBBase; uint64_t SectionBOffset = AddrB - SectionBBase;
@ -483,7 +483,48 @@ relocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
addRelocationForSection(R, SectionAID); addRelocationForSection(R, SectionAID);
addRelocationForSection(R, SectionBID); 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( relocation_iterator RuntimeDyldMachO::processRelocationRef(
@ -498,17 +539,22 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
uint32_t RelType = MachO->getAnyRelocationType(RE); uint32_t RelType = MachO->getAnyRelocationType(RE);
// FIXME: Properly handle scattered relocations. // FIXME: Properly handle scattered relocations.
// For now, optimistically skip these: they can often be ignored, as // Special case the couple of scattered relocations that we know how
// the static linker will already have applied the relocation, and it // to handle: SECTDIFF relocations, and scattered VANILLA relocations
// only needs to be reapplied if symbols move relative to one another. // on I386.
// Note: This will fail horribly where the relocations *do* need to be // For all other scattered relocations, just bail out and hope for the
// applied, but that was already the case. // 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 (MachO->isRelocationScattered(RE)) {
if (RelType == MachO::GENERIC_RELOC_SECTDIFF || if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID); return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID);
else if (Arch == Triple::x86 && RelType == MachO::GENERIC_RELOC_VANILLA)
return ++RelI; return processI386ScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID);
else
return ++RelI;
} }
RelocationValueRef Value; RelocationValueRef Value;

View File

@ -71,6 +71,12 @@ private:
ObjectImage &ObjImg, ObjectImage &ObjImg,
ObjSectionToIDMap &ObjSectionToID); ObjSectionToIDMap &ObjSectionToID);
relocation_iterator processI386ScatteredVANILLA(
unsigned SectionID,
relocation_iterator RelI,
ObjectImage &ObjImg,
ObjSectionToIDMap &ObjSectionToID);
struct EHFrameRelatedSections { struct EHFrameRelatedSections {
EHFrameRelatedSections() EHFrameRelatedSections()
: EHFrameSID(RTDYLD_INVALID_SECTION_ID), : EHFrameSID(RTDYLD_INVALID_SECTION_ID),