[RuntimeDyld][MachO] Add support for SUBTRACTOR relocations between anonymous

symbols on x86-64.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270157 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lang Hames 2016-05-19 23:26:05 +00:00
parent 02e249fb8e
commit 8c34a3f83c
2 changed files with 79 additions and 18 deletions

View File

@ -157,10 +157,10 @@ private:
Expected<relocation_iterator> Expected<relocation_iterator>
processSubtractRelocation(unsigned SectionID, relocation_iterator RelI, processSubtractRelocation(unsigned SectionID, relocation_iterator RelI,
const ObjectFile &BaseObjT, const MachOObjectFile &BaseObj,
ObjSectionToIDMap &ObjSectionToID) { ObjSectionToIDMap &ObjSectionToID) {
const MachOObjectFile &Obj = const MachOObjectFile &Obj =
static_cast<const MachOObjectFile&>(BaseObjT); static_cast<const MachOObjectFile&>(BaseObj);
MachO::any_relocation_info RE = MachO::any_relocation_info RE =
Obj.getRelocation(RelI->getRawDataRefImpl()); Obj.getRelocation(RelI->getRawDataRefImpl());
@ -168,23 +168,60 @@ private:
uint64_t Offset = RelI->getOffset(); uint64_t Offset = RelI->getOffset();
uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset); uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset);
unsigned NumBytes = 1 << Size; unsigned NumBytes = 1 << Size;
Expected<StringRef> SubtrahendNameOrErr = RelI->getSymbol()->getName();
if (!SubtrahendNameOrErr)
return SubtrahendNameOrErr.takeError();
auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr);
unsigned SectionBID = SubtrahendI->second.getSectionID();
uint64_t SectionBOffset = SubtrahendI->second.getOffset();
int64_t Addend = int64_t Addend =
SignExtend64(readBytesUnaligned(LocalAddress, NumBytes), NumBytes * 8); SignExtend64(readBytesUnaligned(LocalAddress, NumBytes), NumBytes * 8);
unsigned SectionBID = ~0U;
uint64_t SectionBOffset = 0;
MachO::any_relocation_info RelInfo =
Obj.getRelocation(RelI->getRawDataRefImpl());
bool AIsExternal = BaseObj.getPlainRelocationExternal(RelInfo);
if (AIsExternal) {
Expected<StringRef> SubtrahendNameOrErr = RelI->getSymbol()->getName();
if (!SubtrahendNameOrErr)
return SubtrahendNameOrErr.takeError();
auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr);
SectionBID = SubtrahendI->second.getSectionID();
SectionBOffset = SubtrahendI->second.getOffset();
} else {
SectionRef SecB = Obj.getAnyRelocationSection(RelInfo);
bool IsCode = SecB.isText();
Expected<unsigned> SectionBIDOrErr =
findOrEmitSection(Obj, SecB, IsCode, ObjSectionToID);
if (!SectionBIDOrErr)
return SectionBIDOrErr.takeError();
SectionBID = *SectionBIDOrErr;
Addend += SecB.getAddress();
}
++RelI; ++RelI;
Expected<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName();
if (!MinuendNameOrErr) unsigned SectionAID = ~0U;
return MinuendNameOrErr.takeError(); uint64_t SectionAOffset = 0;
auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr);
unsigned SectionAID = MinuendI->second.getSectionID(); RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl());
uint64_t SectionAOffset = MinuendI->second.getOffset();
bool BIsExternal = BaseObj.getPlainRelocationExternal(RelInfo);
if (BIsExternal) {
Expected<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName();
if (!MinuendNameOrErr)
return MinuendNameOrErr.takeError();
auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr);
SectionAID = MinuendI->second.getSectionID();
SectionAOffset = MinuendI->second.getOffset();
} else {
SectionRef SecA = Obj.getAnyRelocationSection(RelInfo);
bool IsCode = SecA.isText();
Expected<unsigned> SectionAIDOrErr =
findOrEmitSection(Obj, SecA, IsCode, ObjSectionToID);
if (!SectionAIDOrErr)
return SectionAIDOrErr.takeError();
SectionAID = *SectionAIDOrErr;
Addend -= SecA.getAddress();
}
RelocationEntry R(SectionID, Offset, MachO::X86_64_RELOC_SUBTRACTOR, (uint64_t)Addend, RelocationEntry R(SectionID, Offset, MachO::X86_64_RELOC_SUBTRACTOR, (uint64_t)Addend,
SectionAID, SectionAOffset, SectionBID, SectionBOffset, SectionAID, SectionAOffset, SectionBID, SectionBOffset,

View File

@ -62,11 +62,26 @@ z2:
.globl abssym .globl abssym
abssym = 0xdeadbeef abssym = 0xdeadbeef
# Test subtractor relocations. # Test subtractor relocations between named symbols.
# rtdyld-check: *{8}z3 = z4 - z5 + 4 # rtdyld-check: *{8}z3a = z4 - z5 + 4
z3: z3a:
.quad z4 - z5 + 4 .quad z4 - z5 + 4
# Test subtractor relocations between anonymous symbols.
# rtdyld-check: *{8}z3b = (section_addr(test_x86-64.o, _tmp3) + 4) - (section_addr(test_x86-64.o, _tmp4)) + 8
z3b:
.quad Lanondiff_1 - Lanondiff_2 + 8
# Test subtractor relocations between named and anonymous symbols.
# rtdyld-check: *{8}z3c = z4 - (section_addr(test_x86-64.o, _tmp4)) + 12
z3c:
.quad z4 - Lanondiff_2 + 12
# Test subtractor relocations between anonymous and named symbols.
# rtdyld-check: *{8}z3d = (section_addr(test_x86-64.o, _tmp3) + 4) - z4 + 16
z3d:
.quad Lanondiff_1 - z4 + 16
.section __DATA,_tmp1 .section __DATA,_tmp1
z4: z4:
.byte 1 .byte 1
@ -75,4 +90,13 @@ z4:
z5: z5:
.byte 1 .byte 1
.section __DATA,_tmp3
.long 1 # padding to make sure we handle non-zero offsets.
Lanondiff_1:
.byte 1
.section __DATA,_tmp4
Lanondiff_2:
.byte 1
.subsections_via_symbols .subsections_via_symbols