19 #define DEBUG_TYPE "jitlink"
60 return RI.
r_extern ? MachOPointer64 : MachOPointer64Anon;
62 return MachOPointer32;
86 return MachOPageOffset12;
90 return MachOGOTPage21;
94 return MachOGOTPageOffset12;
98 return MachOPointerToGOT;
102 return MachOPairedAddend;
106 return MachOTLVPage21;
110 return MachOTLVPageOffset12;
114 return make_error<JITLinkError>(
115 "Unsupported arm64 relocation: address=" +
119 ", pc_rel=" + (RI.
r_pcrel ?
"true" :
"false") +
120 ", extern=" + (RI.
r_extern ?
"true" :
"false") +
124 using PairRelocInfo = std::tuple<Edge::Kind, Symbol *, uint64_t>;
136 assert(((SubtractorKind == MachODelta32 && SubRI.
r_length == 2) ||
137 (SubtractorKind == MachODelta64 && SubRI.
r_length == 3)) &&
138 "Subtractor kind should match length");
139 assert(SubRI.
r_extern &&
"SUBTRACTOR reloc symbol should be extern");
140 assert(!SubRI.
r_pcrel &&
"SUBTRACTOR reloc should not be PCRel");
142 if (UnsignedRelItr == RelEnd)
143 return make_error<JITLinkError>(
"arm64 SUBTRACTOR without paired "
144 "UNSIGNED relocation");
146 auto UnsignedRI = getRelocationInfo(UnsignedRelItr);
148 if (SubRI.
r_address != UnsignedRI.r_address)
149 return make_error<JITLinkError>(
"arm64 SUBTRACTOR and paired UNSIGNED "
150 "point to different addresses");
152 if (SubRI.
r_length != UnsignedRI.r_length)
153 return make_error<JITLinkError>(
"length of arm64 SUBTRACTOR and paired "
154 "UNSIGNED reloc must match");
157 if (
auto FromSymbolOrErr = findSymbolByIndex(SubRI.
r_symbolnum))
158 FromSymbol = FromSymbolOrErr->GraphSymbol;
160 return FromSymbolOrErr.takeError();
165 FixupValue = *(
const little64_t *)FixupContent;
167 FixupValue = *(
const little32_t *)FixupContent;
171 Symbol *ToSymbol =
nullptr;
172 if (UnsignedRI.r_extern) {
174 if (
auto ToSymbolOrErr = findSymbolByIndex(UnsignedRI.r_symbolnum))
175 ToSymbol = ToSymbolOrErr->GraphSymbol;
177 return ToSymbolOrErr.takeError();
179 auto ToSymbolSec = findSectionByIndex(UnsignedRI.r_symbolnum - 1);
181 return ToSymbolSec.takeError();
182 ToSymbol = getSymbolByAddress(*ToSymbolSec, ToSymbolSec->Address);
183 assert(ToSymbol &&
"No symbol for section");
191 TargetSymbol = ToSymbol;
193 Addend = FixupValue + (FixupAddress - FromSymbol->
getAddress());
196 TargetSymbol = &*FromSymbol;
199 Addend = FixupValue - (FixupAddress - ToSymbol->
getAddress());
202 return make_error<JITLinkError>(
"SUBTRACTOR relocation must fix up "
203 "either 'A' or 'B' (or a symbol in one "
204 "of their alt-entry groups)");
207 return PairRelocInfo(DeltaKind, TargetSymbol, Addend);
210 Error addRelocations()
override {
222 if (
S.relocation_begin() !=
S.relocation_end())
223 return make_error<JITLinkError>(
"Virtual section contains "
231 return NSec.takeError();
236 if (!NSec->GraphSection) {
238 dbgs() <<
" Skipping relocations for MachO section "
239 << NSec->SegName <<
"/" << NSec->SectName
240 <<
" which has no associated graph section\n";
246 for (
auto RelItr =
S.relocation_begin(), RelEnd =
S.relocation_end();
247 RelItr != RelEnd; ++RelItr) {
252 auto MachORelocKind = getRelocationKind(RI);
254 return MachORelocKind.takeError();
260 dbgs() <<
" " << NSec->SectName <<
" + "
265 Block *BlockToFix =
nullptr;
267 auto SymbolToFixOrErr = findSymbolByAddress(*NSec, FixupAddress);
268 if (!SymbolToFixOrErr)
269 return SymbolToFixOrErr.takeError();
270 BlockToFix = &SymbolToFixOrErr->getBlock();
275 return make_error<JITLinkError>(
276 "Relocation content extends past end of fixup block");
285 Symbol *TargetSymbol =
nullptr;
288 if (*MachORelocKind == MachOPairedAddend) {
294 if (RelItr == RelEnd)
295 return make_error<JITLinkError>(
"Unpaired Addend reloc at " +
296 formatv(
"{0:x16}", FixupAddress));
298 RI = getRelocationInfo(RelItr);
300 MachORelocKind = getRelocationKind(RI);
302 return MachORelocKind.takeError();
304 if (*MachORelocKind != MachOBranch26 &&
305 *MachORelocKind != MachOPage21 &&
306 *MachORelocKind != MachOPageOffset12)
307 return make_error<JITLinkError>(
308 "Invalid relocation pair: Addend + " +
309 StringRef(getMachOARM64RelocationKindName(*MachORelocKind)));
312 dbgs() <<
" Addend: value = " <<
formatv(
"{0:x6}", Addend)
314 << getMachOARM64RelocationKindName(*MachORelocKind) <<
"\n";
320 if (PairedFixupAddress != FixupAddress)
321 return make_error<JITLinkError>(
"Paired relocation points at "
325 switch (*MachORelocKind) {
326 case MachOBranch26: {
327 if (
auto TargetSymbolOrErr = findSymbolByIndex(RI.
r_symbolnum))
328 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
330 return TargetSymbolOrErr.takeError();
332 if ((Instr & 0x7fffffff) != 0x14000000)
333 return make_error<JITLinkError>(
"BRANCH26 target is not a B or BL "
334 "instruction with a zero addend");
339 if (
auto TargetSymbolOrErr = findSymbolByIndex(RI.
r_symbolnum))
340 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
342 return TargetSymbolOrErr.takeError();
347 if (
auto TargetSymbolOrErr = findSymbolByIndex(RI.
r_symbolnum))
348 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
350 return TargetSymbolOrErr.takeError();
354 case MachOPointer64Anon: {
356 auto TargetNSec = findSectionByIndex(RI.
r_symbolnum - 1);
358 return TargetNSec.takeError();
359 if (
auto TargetSymbolOrErr =
360 findSymbolByAddress(*TargetNSec, TargetAddress))
361 TargetSymbol = &*TargetSymbolOrErr;
363 return TargetSymbolOrErr.takeError();
364 Addend = TargetAddress - TargetSymbol->
getAddress();
370 case MachOGOTPage21: {
371 if (
auto TargetSymbolOrErr = findSymbolByIndex(RI.
r_symbolnum))
372 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
374 return TargetSymbolOrErr.takeError();
376 if ((Instr & 0xffffffe0) != 0x90000000)
377 return make_error<JITLinkError>(
"PAGE21/GOTPAGE21 target is not an "
378 "ADRP instruction with a zero "
381 if (*MachORelocKind == MachOPage21) {
383 }
else if (*MachORelocKind == MachOTLVPage21) {
385 }
else if (*MachORelocKind == MachOGOTPage21) {
390 case MachOPageOffset12: {
391 if (
auto TargetSymbolOrErr = findSymbolByIndex(RI.
r_symbolnum))
392 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
394 return TargetSymbolOrErr.takeError();
396 uint32_t EncodedAddend = (Instr & 0x003FFC00) >> 10;
397 if (EncodedAddend != 0)
398 return make_error<JITLinkError>(
"GOTPAGEOFF12 target has non-zero "
403 case MachOTLVPageOffset12:
404 case MachOGOTPageOffset12: {
405 if (
auto TargetSymbolOrErr = findSymbolByIndex(RI.
r_symbolnum))
406 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
408 return TargetSymbolOrErr.takeError();
410 if ((Instr & 0xfffffc00) != 0xf9400000)
411 return make_error<JITLinkError>(
"GOTPAGEOFF12 target is not an LDR "
412 "immediate instruction with a zero "
415 if (*MachORelocKind == MachOTLVPageOffset12) {
417 }
else if (*MachORelocKind == MachOGOTPageOffset12) {
422 case MachOPointerToGOT:
423 if (
auto TargetSymbolOrErr = findSymbolByIndex(RI.
r_symbolnum))
424 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
426 return TargetSymbolOrErr.takeError();
438 parsePairRelocation(*BlockToFix, *MachORelocKind, RI,
439 FixupAddress, FixupContent, ++RelItr, RelEnd);
441 return PairInfo.takeError();
442 std::tie(
Kind, TargetSymbol, Addend) = *PairInfo;
443 assert(TargetSymbol &&
"No target symbol from parsePairRelocation?");
459 *TargetSymbol, Addend);
466 const char *getMachOARM64RelocationKindName(
Edge::Kind R) {
469 return "MachOBranch26";
471 return "MachOPointer64";
472 case MachOPointer64Anon:
473 return "MachOPointer64Anon";
475 return "MachOPage21";
476 case MachOPageOffset12:
477 return "MachOPageOffset12";
479 return "MachOGOTPage21";
480 case MachOGOTPageOffset12:
481 return "MachOGOTPageOffset12";
483 return "MachOTLVPage21";
484 case MachOTLVPageOffset12:
485 return "MachOTLVPageOffset12";
486 case MachOPointerToGOT:
487 return "MachOPointerToGOT";
488 case MachOPairedAddend:
489 return "MachOPairedAddend";
490 case MachOLDRLiteral19:
491 return "MachOLDRLiteral19";
493 return "MachODelta32";
495 return "MachODelta64";
496 case MachONegDelta32:
497 return "MachONegDelta32";
498 case MachONegDelta64:
499 return "MachONegDelta64";
505 unsigned NumSymbols = 0;
527 std::unique_ptr<LinkGraph>
G,
543 return MachOObj.takeError();
544 return MachOLinkGraphBuilder_arm64(**MachOObj).buildGraph();
548 std::unique_ptr<JITLinkContext> Ctx) {
552 if (Ctx->shouldAddDefaultTargetPasses(
G->getTargetTriple())) {
554 if (
auto MarkLive = Ctx->getMarkLivePass(
G->getTargetTriple()))
576 if (
auto Err = Ctx->modifyPassConfig(*
G, Config))
577 return Ctx->notifyFailed(
std::move(Err));