1 //===---- MachO_arm64.cpp - JIT linker implementation for MachO/arm64 -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // MachO/arm64 jit-link implementation. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ExecutionEngine/JITLink/MachO_arm64.h" 14 #include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h" 15 #include "llvm/ExecutionEngine/JITLink/aarch64.h" 16 17 #include "DefineExternalSectionStartAndEndSymbols.h" 18 #include "MachOLinkGraphBuilder.h" 19 20 #define DEBUG_TYPE "jitlink" 21 22 using namespace llvm; 23 using namespace llvm::jitlink; 24 25 namespace { 26 27 class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder { 28 public: 29 MachOLinkGraphBuilder_arm64(const object::MachOObjectFile &Obj, 30 SubtargetFeatures Features) 31 : MachOLinkGraphBuilder(Obj, Triple("arm64-apple-darwin"), 32 std::move(Features), aarch64::getEdgeKindName), 33 NumSymbols(Obj.getSymtabLoadCommand().nsyms) {} 34 35 private: 36 enum MachOARM64RelocationKind : Edge::Kind { 37 MachOBranch26 = Edge::FirstRelocation, 38 MachOPointer32, 39 MachOPointer64, 40 MachOPointer64Anon, 41 MachOPage21, 42 MachOPageOffset12, 43 MachOGOTPage21, 44 MachOGOTPageOffset12, 45 MachOTLVPage21, 46 MachOTLVPageOffset12, 47 MachOPointerToGOT, 48 MachOPairedAddend, 49 MachOLDRLiteral19, 50 MachODelta32, 51 MachODelta64, 52 MachONegDelta32, 53 MachONegDelta64, 54 }; 55 56 static Expected<MachOARM64RelocationKind> 57 getRelocationKind(const MachO::relocation_info &RI) { 58 switch (RI.r_type) { 59 case MachO::ARM64_RELOC_UNSIGNED: 60 if (!RI.r_pcrel) { 61 if (RI.r_length == 3) 62 return RI.r_extern ? MachOPointer64 : MachOPointer64Anon; 63 else if (RI.r_length == 2) 64 return MachOPointer32; 65 } 66 break; 67 case MachO::ARM64_RELOC_SUBTRACTOR: 68 // SUBTRACTOR must be non-pc-rel, extern, with length 2 or 3. 69 // Initially represent SUBTRACTOR relocations with 'Delta<W>'. 70 // They may be turned into NegDelta<W> by parsePairRelocation. 71 if (!RI.r_pcrel && RI.r_extern) { 72 if (RI.r_length == 2) 73 return MachODelta32; 74 else if (RI.r_length == 3) 75 return MachODelta64; 76 } 77 break; 78 case MachO::ARM64_RELOC_BRANCH26: 79 if (RI.r_pcrel && RI.r_extern && RI.r_length == 2) 80 return MachOBranch26; 81 break; 82 case MachO::ARM64_RELOC_PAGE21: 83 if (RI.r_pcrel && RI.r_extern && RI.r_length == 2) 84 return MachOPage21; 85 break; 86 case MachO::ARM64_RELOC_PAGEOFF12: 87 if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2) 88 return MachOPageOffset12; 89 break; 90 case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 91 if (RI.r_pcrel && RI.r_extern && RI.r_length == 2) 92 return MachOGOTPage21; 93 break; 94 case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: 95 if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2) 96 return MachOGOTPageOffset12; 97 break; 98 case MachO::ARM64_RELOC_POINTER_TO_GOT: 99 if (RI.r_pcrel && RI.r_extern && RI.r_length == 2) 100 return MachOPointerToGOT; 101 break; 102 case MachO::ARM64_RELOC_ADDEND: 103 if (!RI.r_pcrel && !RI.r_extern && RI.r_length == 2) 104 return MachOPairedAddend; 105 break; 106 case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21: 107 if (RI.r_pcrel && RI.r_extern && RI.r_length == 2) 108 return MachOTLVPage21; 109 break; 110 case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: 111 if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2) 112 return MachOTLVPageOffset12; 113 break; 114 } 115 116 return make_error<JITLinkError>( 117 "Unsupported arm64 relocation: address=" + 118 formatv("{0:x8}", RI.r_address) + 119 ", symbolnum=" + formatv("{0:x6}", RI.r_symbolnum) + 120 ", kind=" + formatv("{0:x1}", RI.r_type) + 121 ", pc_rel=" + (RI.r_pcrel ? "true" : "false") + 122 ", extern=" + (RI.r_extern ? "true" : "false") + 123 ", length=" + formatv("{0:d}", RI.r_length)); 124 } 125 126 using PairRelocInfo = std::tuple<Edge::Kind, Symbol *, uint64_t>; 127 128 // Parses paired SUBTRACTOR/UNSIGNED relocations and, on success, 129 // returns the edge kind and addend to be used. 130 Expected<PairRelocInfo> 131 parsePairRelocation(Block &BlockToFix, Edge::Kind SubtractorKind, 132 const MachO::relocation_info &SubRI, 133 orc::ExecutorAddr FixupAddress, const char *FixupContent, 134 object::relocation_iterator &UnsignedRelItr, 135 object::relocation_iterator &RelEnd) { 136 using namespace support; 137 138 assert(((SubtractorKind == MachODelta32 && SubRI.r_length == 2) || 139 (SubtractorKind == MachODelta64 && SubRI.r_length == 3)) && 140 "Subtractor kind should match length"); 141 assert(SubRI.r_extern && "SUBTRACTOR reloc symbol should be extern"); 142 assert(!SubRI.r_pcrel && "SUBTRACTOR reloc should not be PCRel"); 143 144 if (UnsignedRelItr == RelEnd) 145 return make_error<JITLinkError>("arm64 SUBTRACTOR without paired " 146 "UNSIGNED relocation"); 147 148 auto UnsignedRI = getRelocationInfo(UnsignedRelItr); 149 150 if (SubRI.r_address != UnsignedRI.r_address) 151 return make_error<JITLinkError>("arm64 SUBTRACTOR and paired UNSIGNED " 152 "point to different addresses"); 153 154 if (SubRI.r_length != UnsignedRI.r_length) 155 return make_error<JITLinkError>("length of arm64 SUBTRACTOR and paired " 156 "UNSIGNED reloc must match"); 157 158 Symbol *FromSymbol; 159 if (auto FromSymbolOrErr = findSymbolByIndex(SubRI.r_symbolnum)) 160 FromSymbol = FromSymbolOrErr->GraphSymbol; 161 else 162 return FromSymbolOrErr.takeError(); 163 164 // Read the current fixup value. 165 uint64_t FixupValue = 0; 166 if (SubRI.r_length == 3) 167 FixupValue = *(const little64_t *)FixupContent; 168 else 169 FixupValue = *(const little32_t *)FixupContent; 170 171 // Find 'ToSymbol' using symbol number or address, depending on whether the 172 // paired UNSIGNED relocation is extern. 173 Symbol *ToSymbol = nullptr; 174 if (UnsignedRI.r_extern) { 175 // Find target symbol by symbol index. 176 if (auto ToSymbolOrErr = findSymbolByIndex(UnsignedRI.r_symbolnum)) 177 ToSymbol = ToSymbolOrErr->GraphSymbol; 178 else 179 return ToSymbolOrErr.takeError(); 180 } else { 181 auto ToSymbolSec = findSectionByIndex(UnsignedRI.r_symbolnum - 1); 182 if (!ToSymbolSec) 183 return ToSymbolSec.takeError(); 184 ToSymbol = getSymbolByAddress(*ToSymbolSec, ToSymbolSec->Address); 185 assert(ToSymbol && "No symbol for section"); 186 FixupValue -= ToSymbol->getAddress().getValue(); 187 } 188 189 Edge::Kind DeltaKind; 190 Symbol *TargetSymbol; 191 uint64_t Addend; 192 193 bool FixingFromSymbol = true; 194 if (&BlockToFix == &FromSymbol->getAddressable()) { 195 if (LLVM_UNLIKELY(&BlockToFix == &ToSymbol->getAddressable())) { 196 // From and To are symbols in the same block. Decide direction by offset 197 // instead. 198 if (ToSymbol->getAddress() > FixupAddress) 199 FixingFromSymbol = true; 200 else if (FromSymbol->getAddress() > FixupAddress) 201 FixingFromSymbol = false; 202 else 203 FixingFromSymbol = FromSymbol->getAddress() >= ToSymbol->getAddress(); 204 } else 205 FixingFromSymbol = true; 206 } else { 207 if (&BlockToFix == &ToSymbol->getAddressable()) 208 FixingFromSymbol = false; 209 else { 210 // BlockToFix was neither FromSymbol nor ToSymbol. 211 return make_error<JITLinkError>("SUBTRACTOR relocation must fix up " 212 "either 'A' or 'B' (or a symbol in one " 213 "of their alt-entry groups)"); 214 } 215 } 216 217 if (FixingFromSymbol) { 218 TargetSymbol = ToSymbol; 219 DeltaKind = (SubRI.r_length == 3) ? aarch64::Delta64 : aarch64::Delta32; 220 Addend = FixupValue + (FixupAddress - FromSymbol->getAddress()); 221 // FIXME: handle extern 'from'. 222 } else { 223 TargetSymbol = &*FromSymbol; 224 DeltaKind = 225 (SubRI.r_length == 3) ? aarch64::NegDelta64 : aarch64::NegDelta32; 226 Addend = FixupValue - (FixupAddress - ToSymbol->getAddress()); 227 } 228 229 return PairRelocInfo(DeltaKind, TargetSymbol, Addend); 230 } 231 232 Error addRelocations() override { 233 using namespace support; 234 auto &Obj = getObject(); 235 236 LLVM_DEBUG(dbgs() << "Processing relocations:\n"); 237 238 for (auto &S : Obj.sections()) { 239 240 orc::ExecutorAddr SectionAddress(S.getAddress()); 241 242 // Skip relocations virtual sections. 243 if (S.isVirtual()) { 244 if (S.relocation_begin() != S.relocation_end()) 245 return make_error<JITLinkError>("Virtual section contains " 246 "relocations"); 247 continue; 248 } 249 250 auto NSec = 251 findSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl())); 252 if (!NSec) 253 return NSec.takeError(); 254 255 // Skip relocations for MachO sections without corresponding graph 256 // sections. 257 { 258 if (!NSec->GraphSection) { 259 LLVM_DEBUG({ 260 dbgs() << " Skipping relocations for MachO section " 261 << NSec->SegName << "/" << NSec->SectName 262 << " which has no associated graph section\n"; 263 }); 264 continue; 265 } 266 } 267 268 for (auto RelItr = S.relocation_begin(), RelEnd = S.relocation_end(); 269 RelItr != RelEnd; ++RelItr) { 270 271 MachO::relocation_info RI = getRelocationInfo(RelItr); 272 273 // Validate the relocation kind. 274 auto MachORelocKind = getRelocationKind(RI); 275 if (!MachORelocKind) 276 return MachORelocKind.takeError(); 277 278 // Find the address of the value to fix up. 279 orc::ExecutorAddr FixupAddress = 280 SectionAddress + (uint32_t)RI.r_address; 281 LLVM_DEBUG({ 282 dbgs() << " " << NSec->SectName << " + " 283 << formatv("{0:x8}", RI.r_address) << ":\n"; 284 }); 285 286 // Find the block that the fixup points to. 287 Block *BlockToFix = nullptr; 288 { 289 auto SymbolToFixOrErr = findSymbolByAddress(*NSec, FixupAddress); 290 if (!SymbolToFixOrErr) 291 return SymbolToFixOrErr.takeError(); 292 BlockToFix = &SymbolToFixOrErr->getBlock(); 293 } 294 295 if (FixupAddress + orc::ExecutorAddrDiff(1ULL << RI.r_length) > 296 BlockToFix->getAddress() + BlockToFix->getContent().size()) 297 return make_error<JITLinkError>( 298 "Relocation content extends past end of fixup block"); 299 300 Edge::Kind Kind = Edge::Invalid; 301 302 // Get a pointer to the fixup content. 303 const char *FixupContent = BlockToFix->getContent().data() + 304 (FixupAddress - BlockToFix->getAddress()); 305 306 // The target symbol and addend will be populated by the switch below. 307 Symbol *TargetSymbol = nullptr; 308 uint64_t Addend = 0; 309 310 if (*MachORelocKind == MachOPairedAddend) { 311 // If this is an Addend relocation then process it and move to the 312 // paired reloc. 313 314 Addend = SignExtend64(RI.r_symbolnum, 24); 315 316 ++RelItr; 317 if (RelItr == RelEnd) 318 return make_error<JITLinkError>("Unpaired Addend reloc at " + 319 formatv("{0:x16}", FixupAddress)); 320 RI = getRelocationInfo(RelItr); 321 322 MachORelocKind = getRelocationKind(RI); 323 if (!MachORelocKind) 324 return MachORelocKind.takeError(); 325 326 if (*MachORelocKind != MachOBranch26 && 327 *MachORelocKind != MachOPage21 && 328 *MachORelocKind != MachOPageOffset12) 329 return make_error<JITLinkError>( 330 "Invalid relocation pair: Addend + " + 331 StringRef(getMachOARM64RelocationKindName(*MachORelocKind))); 332 333 LLVM_DEBUG({ 334 dbgs() << " Addend: value = " << formatv("{0:x6}", Addend) 335 << ", pair is " 336 << getMachOARM64RelocationKindName(*MachORelocKind) << "\n"; 337 }); 338 339 // Find the address of the value to fix up. 340 orc::ExecutorAddr PairedFixupAddress = 341 SectionAddress + (uint32_t)RI.r_address; 342 if (PairedFixupAddress != FixupAddress) 343 return make_error<JITLinkError>("Paired relocation points at " 344 "different target"); 345 } 346 347 switch (*MachORelocKind) { 348 case MachOBranch26: { 349 if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum)) 350 TargetSymbol = TargetSymbolOrErr->GraphSymbol; 351 else 352 return TargetSymbolOrErr.takeError(); 353 uint32_t Instr = *(const ulittle32_t *)FixupContent; 354 if ((Instr & 0x7fffffff) != 0x14000000) 355 return make_error<JITLinkError>("BRANCH26 target is not a B or BL " 356 "instruction with a zero addend"); 357 Kind = aarch64::Branch26PCRel; 358 break; 359 } 360 case MachOPointer32: 361 if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum)) 362 TargetSymbol = TargetSymbolOrErr->GraphSymbol; 363 else 364 return TargetSymbolOrErr.takeError(); 365 Addend = *(const ulittle32_t *)FixupContent; 366 Kind = aarch64::Pointer32; 367 break; 368 case MachOPointer64: 369 if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum)) 370 TargetSymbol = TargetSymbolOrErr->GraphSymbol; 371 else 372 return TargetSymbolOrErr.takeError(); 373 Addend = *(const ulittle64_t *)FixupContent; 374 Kind = aarch64::Pointer64; 375 break; 376 case MachOPointer64Anon: { 377 orc::ExecutorAddr TargetAddress(*(const ulittle64_t *)FixupContent); 378 auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1); 379 if (!TargetNSec) 380 return TargetNSec.takeError(); 381 if (auto TargetSymbolOrErr = 382 findSymbolByAddress(*TargetNSec, TargetAddress)) 383 TargetSymbol = &*TargetSymbolOrErr; 384 else 385 return TargetSymbolOrErr.takeError(); 386 Addend = TargetAddress - TargetSymbol->getAddress(); 387 Kind = aarch64::Pointer64; 388 break; 389 } 390 case MachOPage21: 391 case MachOGOTPage21: 392 case MachOTLVPage21: { 393 if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum)) 394 TargetSymbol = TargetSymbolOrErr->GraphSymbol; 395 else 396 return TargetSymbolOrErr.takeError(); 397 uint32_t Instr = *(const ulittle32_t *)FixupContent; 398 if ((Instr & 0xffffffe0) != 0x90000000) 399 return make_error<JITLinkError>("PAGE21/GOTPAGE21 target is not an " 400 "ADRP instruction with a zero " 401 "addend"); 402 403 if (*MachORelocKind == MachOPage21) { 404 Kind = aarch64::Page21; 405 } else if (*MachORelocKind == MachOGOTPage21) { 406 Kind = aarch64::RequestGOTAndTransformToPage21; 407 } else if (*MachORelocKind == MachOTLVPage21) { 408 Kind = aarch64::RequestTLVPAndTransformToPage21; 409 } 410 break; 411 } 412 case MachOPageOffset12: { 413 if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum)) 414 TargetSymbol = TargetSymbolOrErr->GraphSymbol; 415 else 416 return TargetSymbolOrErr.takeError(); 417 uint32_t Instr = *(const ulittle32_t *)FixupContent; 418 uint32_t EncodedAddend = (Instr & 0x003FFC00) >> 10; 419 if (EncodedAddend != 0) 420 return make_error<JITLinkError>("GOTPAGEOFF12 target has non-zero " 421 "encoded addend"); 422 Kind = aarch64::PageOffset12; 423 break; 424 } 425 case MachOGOTPageOffset12: 426 case MachOTLVPageOffset12: { 427 if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum)) 428 TargetSymbol = TargetSymbolOrErr->GraphSymbol; 429 else 430 return TargetSymbolOrErr.takeError(); 431 uint32_t Instr = *(const ulittle32_t *)FixupContent; 432 if ((Instr & 0xfffffc00) != 0xf9400000) 433 return make_error<JITLinkError>("GOTPAGEOFF12 target is not an LDR " 434 "immediate instruction with a zero " 435 "addend"); 436 437 if (*MachORelocKind == MachOGOTPageOffset12) { 438 Kind = aarch64::RequestGOTAndTransformToPageOffset12; 439 } else if (*MachORelocKind == MachOTLVPageOffset12) { 440 Kind = aarch64::RequestTLVPAndTransformToPageOffset12; 441 } 442 break; 443 } 444 case MachOPointerToGOT: 445 if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum)) 446 TargetSymbol = TargetSymbolOrErr->GraphSymbol; 447 else 448 return TargetSymbolOrErr.takeError(); 449 450 Kind = aarch64::RequestGOTAndTransformToDelta32; 451 break; 452 case MachODelta32: 453 case MachODelta64: { 454 // We use Delta32/Delta64 to represent SUBTRACTOR relocations. 455 // parsePairRelocation handles the paired reloc, and returns the 456 // edge kind to be used (either Delta32/Delta64, or 457 // NegDelta32/NegDelta64, depending on the direction of the 458 // subtraction) along with the addend. 459 auto PairInfo = 460 parsePairRelocation(*BlockToFix, *MachORelocKind, RI, 461 FixupAddress, FixupContent, ++RelItr, RelEnd); 462 if (!PairInfo) 463 return PairInfo.takeError(); 464 std::tie(Kind, TargetSymbol, Addend) = *PairInfo; 465 assert(TargetSymbol && "No target symbol from parsePairRelocation?"); 466 break; 467 } 468 default: 469 llvm_unreachable("Special relocation kind should not appear in " 470 "mach-o file"); 471 } 472 473 LLVM_DEBUG({ 474 dbgs() << " "; 475 Edge GE(Kind, FixupAddress - BlockToFix->getAddress(), *TargetSymbol, 476 Addend); 477 printEdge(dbgs(), *BlockToFix, GE, aarch64::getEdgeKindName(Kind)); 478 dbgs() << "\n"; 479 }); 480 BlockToFix->addEdge(Kind, FixupAddress - BlockToFix->getAddress(), 481 *TargetSymbol, Addend); 482 } 483 } 484 return Error::success(); 485 } 486 487 /// Return the string name of the given MachO arm64 edge kind. 488 const char *getMachOARM64RelocationKindName(Edge::Kind R) { 489 switch (R) { 490 case MachOBranch26: 491 return "MachOBranch26"; 492 case MachOPointer64: 493 return "MachOPointer64"; 494 case MachOPointer64Anon: 495 return "MachOPointer64Anon"; 496 case MachOPage21: 497 return "MachOPage21"; 498 case MachOPageOffset12: 499 return "MachOPageOffset12"; 500 case MachOGOTPage21: 501 return "MachOGOTPage21"; 502 case MachOGOTPageOffset12: 503 return "MachOGOTPageOffset12"; 504 case MachOTLVPage21: 505 return "MachOTLVPage21"; 506 case MachOTLVPageOffset12: 507 return "MachOTLVPageOffset12"; 508 case MachOPointerToGOT: 509 return "MachOPointerToGOT"; 510 case MachOPairedAddend: 511 return "MachOPairedAddend"; 512 case MachOLDRLiteral19: 513 return "MachOLDRLiteral19"; 514 case MachODelta32: 515 return "MachODelta32"; 516 case MachODelta64: 517 return "MachODelta64"; 518 case MachONegDelta32: 519 return "MachONegDelta32"; 520 case MachONegDelta64: 521 return "MachONegDelta64"; 522 default: 523 return getGenericEdgeKindName(static_cast<Edge::Kind>(R)); 524 } 525 } 526 527 unsigned NumSymbols = 0; 528 }; 529 530 } // namespace 531 532 namespace llvm { 533 namespace jitlink { 534 535 Error buildTables_MachO_arm64(LinkGraph &G) { 536 LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n"); 537 538 aarch64::GOTTableManager GOT; 539 aarch64::PLTTableManager PLT(GOT); 540 visitExistingEdges(G, GOT, PLT); 541 return Error::success(); 542 } 543 544 class MachOJITLinker_arm64 : public JITLinker<MachOJITLinker_arm64> { 545 friend class JITLinker<MachOJITLinker_arm64>; 546 547 public: 548 MachOJITLinker_arm64(std::unique_ptr<JITLinkContext> Ctx, 549 std::unique_ptr<LinkGraph> G, 550 PassConfiguration PassConfig) 551 : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {} 552 553 private: 554 Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const { 555 return aarch64::applyFixup(G, B, E); 556 } 557 558 uint64_t NullValue = 0; 559 }; 560 561 Expected<std::unique_ptr<LinkGraph>> 562 createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer) { 563 auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer); 564 if (!MachOObj) 565 return MachOObj.takeError(); 566 567 auto Features = (*MachOObj)->getFeatures(); 568 if (!Features) 569 return Features.takeError(); 570 571 return MachOLinkGraphBuilder_arm64(**MachOObj, std::move(*Features)) 572 .buildGraph(); 573 } 574 575 void link_MachO_arm64(std::unique_ptr<LinkGraph> G, 576 std::unique_ptr<JITLinkContext> Ctx) { 577 578 PassConfiguration Config; 579 580 if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) { 581 // Add a mark-live pass. 582 if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple())) 583 Config.PrePrunePasses.push_back(std::move(MarkLive)); 584 else 585 Config.PrePrunePasses.push_back(markAllSymbolsLive); 586 587 // Add compact unwind splitter pass. 588 Config.PrePrunePasses.push_back( 589 CompactUnwindSplitter("__LD,__compact_unwind")); 590 591 // Add eh-frame passes. 592 // FIXME: Prune eh-frames for which compact-unwind is available once 593 // we support compact-unwind registration with libunwind. 594 Config.PrePrunePasses.push_back(createEHFrameSplitterPass_MachO_arm64()); 595 Config.PrePrunePasses.push_back(createEHFrameEdgeFixerPass_MachO_arm64()); 596 597 // Resolve any external section start / end symbols. 598 Config.PostAllocationPasses.push_back( 599 createDefineExternalSectionStartAndEndSymbolsPass( 600 identifyMachOSectionStartAndEndSymbols)); 601 602 // Add an in-place GOT/Stubs pass. 603 Config.PostPrunePasses.push_back(buildTables_MachO_arm64); 604 } 605 606 if (auto Err = Ctx->modifyPassConfig(*G, Config)) 607 return Ctx->notifyFailed(std::move(Err)); 608 609 // Construct a JITLinker and run the link function. 610 MachOJITLinker_arm64::link(std::move(Ctx), std::move(G), std::move(Config)); 611 } 612 613 LinkGraphPassFunction createEHFrameSplitterPass_MachO_arm64() { 614 return DWARFRecordSectionSplitter("__TEXT,__eh_frame"); 615 } 616 617 LinkGraphPassFunction createEHFrameEdgeFixerPass_MachO_arm64() { 618 return EHFrameEdgeFixer("__TEXT,__eh_frame", aarch64::PointerSize, 619 aarch64::Pointer32, aarch64::Pointer64, 620 aarch64::Delta32, aarch64::Delta64, 621 aarch64::NegDelta32); 622 } 623 624 } // end namespace jitlink 625 } // end namespace llvm 626