aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h73
1 files changed, 66 insertions, 7 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
index dbca37747ce8..63598f197070 100644
--- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
+++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
@@ -242,7 +242,7 @@ public:
}
}
- relocation_iterator
+ Expected<relocation_iterator>
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
const ObjectFile &BaseObjT,
ObjSectionToIDMap &ObjSectionToID,
@@ -252,7 +252,9 @@ public:
MachO::any_relocation_info RelInfo =
Obj.getRelocation(RelI->getRawDataRefImpl());
- assert(!Obj.isRelocationScattered(RelInfo) && "");
+ if (Obj.isRelocationScattered(RelInfo))
+ return make_error<RuntimeDyldError>("Scattered relocations not supported "
+ "for MachO AArch64");
// ARM64 has an ARM64_RELOC_ADDEND relocation type that carries an explicit
// addend for the following relocation. If found: (1) store the associated
@@ -270,6 +272,9 @@ public:
RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl());
}
+ if (Obj.getAnyRelocationType(RelInfo) == MachO::ARM64_RELOC_SUBTRACTOR)
+ return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID);
+
RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
RE.Addend = decodeAddend(RE);
@@ -278,8 +283,11 @@ public:
if (ExplicitAddend)
RE.Addend = ExplicitAddend;
- RelocationValueRef Value(
- getRelocationValueRef(Obj, RelI, RE, ObjSectionToID));
+ RelocationValueRef Value;
+ if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID))
+ Value = *ValueOrErr;
+ else
+ return ValueOrErr.takeError();
bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
if (!IsExtern && RE.IsPCRel)
@@ -349,7 +357,15 @@ public:
encodeAddend(LocalAddress, /*Size=*/4, RelType, Value);
break;
}
- case MachO::ARM64_RELOC_SUBTRACTOR:
+ case MachO::ARM64_RELOC_SUBTRACTOR: {
+ uint64_t SectionABase = Sections[RE.Sections.SectionA].getLoadAddress();
+ uint64_t SectionBBase = Sections[RE.Sections.SectionB].getLoadAddress();
+ assert((Value == SectionABase || Value == SectionBBase) &&
+ "Unexpected SUBTRACTOR relocation value.");
+ Value = SectionABase - SectionBBase + RE.Addend;
+ writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);
+ break;
+ }
case MachO::ARM64_RELOC_POINTER_TO_GOT:
case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
@@ -360,8 +376,10 @@ public:
}
}
- void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
- const SectionRef &Section) {}
+ Error finalizeSection(const ObjectFile &Obj, unsigned SectionID,
+ const SectionRef &Section) {
+ return Error::success();
+ }
private:
void processGOTRelocation(const RelocationEntry &RE,
@@ -398,6 +416,47 @@ private:
RE.IsPCRel, RE.Size);
addRelocationForSection(TargetRE, RE.SectionID);
}
+
+ Expected<relocation_iterator>
+ processSubtractRelocation(unsigned SectionID, relocation_iterator RelI,
+ const ObjectFile &BaseObjT,
+ ObjSectionToIDMap &ObjSectionToID) {
+ const MachOObjectFile &Obj =
+ static_cast<const MachOObjectFile&>(BaseObjT);
+ MachO::any_relocation_info RE =
+ Obj.getRelocation(RelI->getRawDataRefImpl());
+
+ unsigned Size = Obj.getAnyRelocationLength(RE);
+ uint64_t Offset = RelI->getOffset();
+ uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset);
+ 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 =
+ SignExtend64(readBytesUnaligned(LocalAddress, NumBytes), NumBytes * 8);
+
+ ++RelI;
+ Expected<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName();
+ if (!MinuendNameOrErr)
+ return MinuendNameOrErr.takeError();
+ auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr);
+ unsigned SectionAID = MinuendI->second.getSectionID();
+ uint64_t SectionAOffset = MinuendI->second.getOffset();
+
+ RelocationEntry R(SectionID, Offset, MachO::ARM64_RELOC_SUBTRACTOR, (uint64_t)Addend,
+ SectionAID, SectionAOffset, SectionBID, SectionBOffset,
+ false, Size);
+
+ addRelocationForSection(R, SectionAID);
+
+ return ++RelI;
+ }
+
};
}