brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.5 KiB · f794780 Raw
726 lines · cpp
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-exception6//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#include "llvm/ExecutionEngine/Orc/Shared/MachOObjectFormat.h"17 18#include "CompactUnwindSupport.h"19#include "DefineExternalSectionStartAndEndSymbols.h"20#include "MachOLinkGraphBuilder.h"21 22#define DEBUG_TYPE "jitlink"23 24using namespace llvm;25using namespace llvm::jitlink;26 27namespace {28 29class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {30public:31  MachOLinkGraphBuilder_arm64(const object::MachOObjectFile &Obj,32                              std::shared_ptr<orc::SymbolStringPool> SSP,33                              SubtargetFeatures Features)34      : MachOLinkGraphBuilder(Obj, std::move(SSP), getObjectTriple(Obj),35                              std::move(Features), aarch64::getEdgeKindName),36        NumSymbols(Obj.getSymtabLoadCommand().nsyms) {}37 38private:39  enum MachOARM64RelocationKind : Edge::Kind {40    MachOBranch26 = Edge::FirstRelocation,41    MachOPointer32,42    MachOPointer64,43    MachOPointer64Anon,44    MachOPointer64Authenticated,45    MachOPage21,46    MachOPageOffset12,47    MachOGOTPage21,48    MachOGOTPageOffset12,49    MachOTLVPage21,50    MachOTLVPageOffset12,51    MachOPointerToGOT,52    MachOPairedAddend,53    MachOLDRLiteral19,54    MachODelta32,55    MachODelta64,56    MachONegDelta32,57    MachONegDelta64,58  };59 60  static Triple getObjectTriple(const object::MachOObjectFile &Obj) {61    // Get the CPU sub-type from the header.62    // jitLink_MachO should already have validated that the buffer is big enough63    // to cover a mach_header64 so this is safe.64    uint32_t CPUSubType =65        *(const support::ulittle32_t *)(Obj.getData().data() + 8);66    CPUSubType &= ~MachO::CPU_SUBTYPE_MASK;67    if (CPUSubType == MachO::CPU_SUBTYPE_ARM64E)68      return Triple("arm64e-apple-darwin");69    return Triple("arm64-apple-darwin");70  }71 72  static Expected<MachOARM64RelocationKind>73  getRelocationKind(const MachO::relocation_info &RI) {74    switch (RI.r_type) {75    case MachO::ARM64_RELOC_UNSIGNED:76      if (!RI.r_pcrel) {77        if (RI.r_length == 3)78          return RI.r_extern ? MachOPointer64 : MachOPointer64Anon;79        else if (RI.r_length == 2)80          return MachOPointer32;81      }82      break;83    case MachO::ARM64_RELOC_SUBTRACTOR:84      // SUBTRACTOR must be non-pc-rel, extern, with length 2 or 3.85      // Initially represent SUBTRACTOR relocations with 'Delta<W>'.86      // They may be turned into NegDelta<W> by parsePairRelocation.87      if (!RI.r_pcrel && RI.r_extern) {88        if (RI.r_length == 2)89          return MachODelta32;90        else if (RI.r_length == 3)91          return MachODelta64;92      }93      break;94    case MachO::ARM64_RELOC_BRANCH26:95      if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)96        return MachOBranch26;97      break;98    case MachO::ARM64_RELOC_PAGE21:99      if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)100        return MachOPage21;101      break;102    case MachO::ARM64_RELOC_PAGEOFF12:103      if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2)104        return MachOPageOffset12;105      break;106    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:107      if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)108        return MachOGOTPage21;109      break;110    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:111      if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2)112        return MachOGOTPageOffset12;113      break;114    case MachO::ARM64_RELOC_POINTER_TO_GOT:115      if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)116        return MachOPointerToGOT;117      break;118    case MachO::ARM64_RELOC_ADDEND:119      if (!RI.r_pcrel && !RI.r_extern && RI.r_length == 2)120        return MachOPairedAddend;121      break;122    case MachO::ARM64_RELOC_AUTHENTICATED_POINTER:123      if (!RI.r_pcrel && RI.r_extern && RI.r_length == 3)124        return MachOPointer64Authenticated;125      break;126    case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:127      if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)128        return MachOTLVPage21;129      break;130    case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:131      if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2)132        return MachOTLVPageOffset12;133      break;134    }135 136    return make_error<JITLinkError>(137        "Unsupported arm64 relocation: address=" +138        formatv("{0:x8}", RI.r_address) +139        ", symbolnum=" + formatv("{0:x6}", RI.r_symbolnum) +140        ", kind=" + formatv("{0:x1}", RI.r_type) +141        ", pc_rel=" + (RI.r_pcrel ? "true" : "false") +142        ", extern=" + (RI.r_extern ? "true" : "false") +143        ", length=" + formatv("{0:d}", RI.r_length));144  }145 146  using PairRelocInfo = std::tuple<Edge::Kind, Symbol *, uint64_t>;147 148  // Parses paired SUBTRACTOR/UNSIGNED relocations and, on success,149  // returns the edge kind and addend to be used.150  Expected<PairRelocInfo>151  parsePairRelocation(Block &BlockToFix, Edge::Kind SubtractorKind,152                      const MachO::relocation_info &SubRI,153                      orc::ExecutorAddr FixupAddress, const char *FixupContent,154                      object::relocation_iterator &UnsignedRelItr,155                      object::relocation_iterator &RelEnd) {156    using namespace support;157 158    assert(((SubtractorKind == MachODelta32 && SubRI.r_length == 2) ||159            (SubtractorKind == MachODelta64 && SubRI.r_length == 3)) &&160           "Subtractor kind should match length");161    assert(SubRI.r_extern && "SUBTRACTOR reloc symbol should be extern");162    assert(!SubRI.r_pcrel && "SUBTRACTOR reloc should not be PCRel");163 164    if (UnsignedRelItr == RelEnd)165      return make_error<JITLinkError>("arm64 SUBTRACTOR without paired "166                                      "UNSIGNED relocation");167 168    auto UnsignedRI = getRelocationInfo(UnsignedRelItr);169 170    if (SubRI.r_address != UnsignedRI.r_address)171      return make_error<JITLinkError>("arm64 SUBTRACTOR and paired UNSIGNED "172                                      "point to different addresses");173 174    if (SubRI.r_length != UnsignedRI.r_length)175      return make_error<JITLinkError>("length of arm64 SUBTRACTOR and paired "176                                      "UNSIGNED reloc must match");177 178    Symbol *FromSymbol;179    if (auto FromSymbolOrErr = findSymbolByIndex(SubRI.r_symbolnum))180      FromSymbol = FromSymbolOrErr->GraphSymbol;181    else182      return FromSymbolOrErr.takeError();183 184    // Read the current fixup value.185    uint64_t FixupValue = 0;186    if (SubRI.r_length == 3)187      FixupValue = *(const little64_t *)FixupContent;188    else189      FixupValue = *(const little32_t *)FixupContent;190 191    // Find 'ToSymbol' using symbol number or address, depending on whether the192    // paired UNSIGNED relocation is extern.193    Symbol *ToSymbol = nullptr;194    if (UnsignedRI.r_extern) {195      // Find target symbol by symbol index.196      if (auto ToSymbolOrErr = findSymbolByIndex(UnsignedRI.r_symbolnum))197        ToSymbol = ToSymbolOrErr->GraphSymbol;198      else199        return ToSymbolOrErr.takeError();200    } else {201      auto ToSymbolSec = findSectionByIndex(UnsignedRI.r_symbolnum - 1);202      if (!ToSymbolSec)203        return ToSymbolSec.takeError();204      ToSymbol = getSymbolByAddress(*ToSymbolSec, ToSymbolSec->Address);205      assert(ToSymbol && "No symbol for section");206      FixupValue -= ToSymbol->getAddress().getValue();207    }208 209    Edge::Kind DeltaKind;210    Symbol *TargetSymbol;211    uint64_t Addend;212 213    bool FixingFromSymbol = true;214    if (&BlockToFix == &FromSymbol->getAddressable()) {215      if (LLVM_UNLIKELY(&BlockToFix == &ToSymbol->getAddressable())) {216        // From and To are symbols in the same block. Decide direction by offset217        // instead.218        if (ToSymbol->getAddress() > FixupAddress)219          FixingFromSymbol = true;220        else if (FromSymbol->getAddress() > FixupAddress)221          FixingFromSymbol = false;222        else223          FixingFromSymbol = FromSymbol->getAddress() >= ToSymbol->getAddress();224      } else225        FixingFromSymbol = true;226    } else {227      if (&BlockToFix == &ToSymbol->getAddressable())228        FixingFromSymbol = false;229      else {230        // BlockToFix was neither FromSymbol nor ToSymbol.231        return make_error<JITLinkError>("SUBTRACTOR relocation must fix up "232                                        "either 'A' or 'B' (or a symbol in one "233                                        "of their alt-entry groups)");234      }235    }236 237    if (FixingFromSymbol) {238      TargetSymbol = ToSymbol;239      DeltaKind = (SubRI.r_length == 3) ? aarch64::Delta64 : aarch64::Delta32;240      Addend = FixupValue + (FixupAddress - FromSymbol->getAddress());241      // FIXME: handle extern 'from'.242    } else {243      TargetSymbol = &*FromSymbol;244      DeltaKind =245          (SubRI.r_length == 3) ? aarch64::NegDelta64 : aarch64::NegDelta32;246      Addend = FixupValue - (FixupAddress - ToSymbol->getAddress());247    }248 249    return PairRelocInfo(DeltaKind, TargetSymbol, Addend);250  }251 252  Error addRelocations() override {253    using namespace support;254    auto &Obj = getObject();255 256    LLVM_DEBUG(dbgs() << "Processing relocations:\n");257 258    for (auto &S : Obj.sections()) {259 260      orc::ExecutorAddr SectionAddress(S.getAddress());261 262      // Skip relocations virtual sections.263      if (S.isVirtual()) {264        if (!S.relocations().empty())265          return make_error<JITLinkError>("Virtual section contains "266                                          "relocations");267        continue;268      }269 270      auto NSec =271          findSectionByIndex(Obj.getSectionIndex(S.getRawDataRefImpl()));272      if (!NSec)273        return NSec.takeError();274 275      // Skip relocations for MachO sections without corresponding graph276      // sections.277      {278        if (!NSec->GraphSection) {279          LLVM_DEBUG({280            dbgs() << "  Skipping relocations for MachO section "281                   << NSec->SegName << "/" << NSec->SectName282                   << " which has no associated graph section\n";283          });284          continue;285        }286      }287 288      for (auto RelItr = S.relocation_begin(), RelEnd = S.relocation_end();289           RelItr != RelEnd; ++RelItr) {290 291        MachO::relocation_info RI = getRelocationInfo(RelItr);292 293        // Validate the relocation kind.294        auto MachORelocKind = getRelocationKind(RI);295        if (!MachORelocKind)296          return MachORelocKind.takeError();297 298        // Find the address of the value to fix up.299        orc::ExecutorAddr FixupAddress =300            SectionAddress + (uint32_t)RI.r_address;301        LLVM_DEBUG({302          dbgs() << "  " << NSec->SectName << " + "303                 << formatv("{0:x8}", RI.r_address) << ":\n";304        });305 306        // Find the block that the fixup points to.307        Block *BlockToFix = nullptr;308        {309          auto SymbolToFixOrErr = findSymbolByAddress(*NSec, FixupAddress);310          if (!SymbolToFixOrErr)311            return SymbolToFixOrErr.takeError();312          BlockToFix = &SymbolToFixOrErr->getBlock();313        }314 315        if (FixupAddress + orc::ExecutorAddrDiff(1ULL << RI.r_length) >316            BlockToFix->getAddress() + BlockToFix->getContent().size())317          return make_error<JITLinkError>(318              "Relocation content extends past end of fixup block");319 320        Edge::Kind Kind = Edge::Invalid;321 322        // Get a pointer to the fixup content.323        const char *FixupContent = BlockToFix->getContent().data() +324                                   (FixupAddress - BlockToFix->getAddress());325 326        // The target symbol and addend will be populated by the switch below.327        Symbol *TargetSymbol = nullptr;328        uint64_t Addend = 0;329 330        if (*MachORelocKind == MachOPairedAddend) {331          // If this is an Addend relocation then process it and move to the332          // paired reloc.333 334          Addend = SignExtend64(RI.r_symbolnum, 24);335 336          ++RelItr;337          if (RelItr == RelEnd)338            return make_error<JITLinkError>("Unpaired Addend reloc at " +339                                            formatv("{0:x16}", FixupAddress));340          RI = getRelocationInfo(RelItr);341 342          MachORelocKind = getRelocationKind(RI);343          if (!MachORelocKind)344            return MachORelocKind.takeError();345 346          if (*MachORelocKind != MachOBranch26 &&347              *MachORelocKind != MachOPage21 &&348              *MachORelocKind != MachOPageOffset12)349            return make_error<JITLinkError>(350                "Invalid relocation pair: Addend + " +351                StringRef(getMachOARM64RelocationKindName(*MachORelocKind)));352 353          LLVM_DEBUG({354            dbgs() << "    Addend: value = " << formatv("{0:x6}", Addend)355                   << ", pair is "356                   << getMachOARM64RelocationKindName(*MachORelocKind) << "\n";357          });358 359          // Find the address of the value to fix up.360          orc::ExecutorAddr PairedFixupAddress =361              SectionAddress + (uint32_t)RI.r_address;362          if (PairedFixupAddress != FixupAddress)363            return make_error<JITLinkError>("Paired relocation points at "364                                            "different target");365        }366 367        switch (*MachORelocKind) {368        case MachOBranch26: {369          if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))370            TargetSymbol = TargetSymbolOrErr->GraphSymbol;371          else372            return TargetSymbolOrErr.takeError();373          uint32_t Instr = *(const ulittle32_t *)FixupContent;374          if ((Instr & 0x7fffffff) != 0x14000000)375            return make_error<JITLinkError>("BRANCH26 target is not a B or BL "376                                            "instruction with a zero addend");377          Kind = aarch64::Branch26PCRel;378          break;379        }380        case MachOPointer32:381          if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))382            TargetSymbol = TargetSymbolOrErr->GraphSymbol;383          else384            return TargetSymbolOrErr.takeError();385          Addend = *(const ulittle32_t *)FixupContent;386          Kind = aarch64::Pointer32;387          break;388        case MachOPointer64:389        case MachOPointer64Authenticated:390          if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))391            TargetSymbol = TargetSymbolOrErr->GraphSymbol;392          else393            return TargetSymbolOrErr.takeError();394          Addend = *(const ulittle64_t *)FixupContent;395          Kind = *MachORelocKind == MachOPointer64396                     ? aarch64::Pointer64397                     : aarch64::Pointer64Authenticated;398          break;399        case MachOPointer64Anon: {400          orc::ExecutorAddr TargetAddress(*(const ulittle64_t *)FixupContent);401          auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);402          if (!TargetNSec)403            return TargetNSec.takeError();404          if (auto TargetSymbolOrErr =405                  findSymbolByAddress(*TargetNSec, TargetAddress))406            TargetSymbol = &*TargetSymbolOrErr;407          else408            return TargetSymbolOrErr.takeError();409          Addend = TargetAddress - TargetSymbol->getAddress();410          Kind = aarch64::Pointer64;411          break;412        }413        case MachOPage21:414        case MachOGOTPage21:415        case MachOTLVPage21: {416          if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))417            TargetSymbol = TargetSymbolOrErr->GraphSymbol;418          else419            return TargetSymbolOrErr.takeError();420          uint32_t Instr = *(const ulittle32_t *)FixupContent;421          if ((Instr & 0xffffffe0) != 0x90000000)422            return make_error<JITLinkError>("PAGE21/GOTPAGE21 target is not an "423                                            "ADRP instruction with a zero "424                                            "addend");425 426          if (*MachORelocKind == MachOPage21) {427            Kind = aarch64::Page21;428          } else if (*MachORelocKind == MachOGOTPage21) {429            Kind = aarch64::RequestGOTAndTransformToPage21;430          } else if (*MachORelocKind == MachOTLVPage21) {431            Kind = aarch64::RequestTLVPAndTransformToPage21;432          }433          break;434        }435        case MachOPageOffset12: {436          if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))437            TargetSymbol = TargetSymbolOrErr->GraphSymbol;438          else439            return TargetSymbolOrErr.takeError();440          uint32_t Instr = *(const ulittle32_t *)FixupContent;441          uint32_t EncodedAddend = (Instr & 0x003FFC00) >> 10;442          if (EncodedAddend != 0)443            return make_error<JITLinkError>("GOTPAGEOFF12 target has non-zero "444                                            "encoded addend");445          Kind = aarch64::PageOffset12;446          break;447        }448        case MachOGOTPageOffset12:449        case MachOTLVPageOffset12: {450          if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))451            TargetSymbol = TargetSymbolOrErr->GraphSymbol;452          else453            return TargetSymbolOrErr.takeError();454          uint32_t Instr = *(const ulittle32_t *)FixupContent;455          if ((Instr & 0xfffffc00) != 0xf9400000)456            return make_error<JITLinkError>("GOTPAGEOFF12 target is not an LDR "457                                            "immediate instruction with a zero "458                                            "addend");459 460          if (*MachORelocKind == MachOGOTPageOffset12) {461            Kind = aarch64::RequestGOTAndTransformToPageOffset12;462          } else if (*MachORelocKind == MachOTLVPageOffset12) {463            Kind = aarch64::RequestTLVPAndTransformToPageOffset12;464          }465          break;466        }467        case MachOPointerToGOT:468          if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))469            TargetSymbol = TargetSymbolOrErr->GraphSymbol;470          else471            return TargetSymbolOrErr.takeError();472 473          Kind = aarch64::RequestGOTAndTransformToDelta32;474          break;475        case MachODelta32:476        case MachODelta64: {477          // We use Delta32/Delta64 to represent SUBTRACTOR relocations.478          // parsePairRelocation handles the paired reloc, and returns the479          // edge kind to be used (either Delta32/Delta64, or480          // NegDelta32/NegDelta64, depending on the direction of the481          // subtraction) along with the addend.482          auto PairInfo =483              parsePairRelocation(*BlockToFix, *MachORelocKind, RI,484                                  FixupAddress, FixupContent, ++RelItr, RelEnd);485          if (!PairInfo)486            return PairInfo.takeError();487          std::tie(Kind, TargetSymbol, Addend) = *PairInfo;488          assert(TargetSymbol && "No target symbol from parsePairRelocation?");489          break;490        }491        default:492          llvm_unreachable("Special relocation kind should not appear in "493                           "mach-o file");494        }495 496        LLVM_DEBUG({497          dbgs() << "    ";498          Edge GE(Kind, FixupAddress - BlockToFix->getAddress(), *TargetSymbol,499                  Addend);500          printEdge(dbgs(), *BlockToFix, GE, aarch64::getEdgeKindName(Kind));501          dbgs() << "\n";502        });503        BlockToFix->addEdge(Kind, FixupAddress - BlockToFix->getAddress(),504                            *TargetSymbol, Addend);505      }506    }507    return Error::success();508  }509 510  /// Return the string name of the given MachO arm64 edge kind.511  const char *getMachOARM64RelocationKindName(Edge::Kind R) {512    switch (R) {513    case MachOBranch26:514      return "MachOBranch26";515    case MachOPointer64:516      return "MachOPointer64";517    case MachOPointer64Anon:518      return "MachOPointer64Anon";519    case MachOPointer64Authenticated:520      return "MachOPointer64Authenticated";521    case MachOPage21:522      return "MachOPage21";523    case MachOPageOffset12:524      return "MachOPageOffset12";525    case MachOGOTPage21:526      return "MachOGOTPage21";527    case MachOGOTPageOffset12:528      return "MachOGOTPageOffset12";529    case MachOTLVPage21:530      return "MachOTLVPage21";531    case MachOTLVPageOffset12:532      return "MachOTLVPageOffset12";533    case MachOPointerToGOT:534      return "MachOPointerToGOT";535    case MachOPairedAddend:536      return "MachOPairedAddend";537    case MachOLDRLiteral19:538      return "MachOLDRLiteral19";539    case MachODelta32:540      return "MachODelta32";541    case MachODelta64:542      return "MachODelta64";543    case MachONegDelta32:544      return "MachONegDelta32";545    case MachONegDelta64:546      return "MachONegDelta64";547    default:548      return getGenericEdgeKindName(R);549    }550  }551 552  unsigned NumSymbols = 0;553};554 555} // namespace556 557namespace llvm {558namespace jitlink {559 560Error buildTables_MachO_arm64(LinkGraph &G) {561  LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");562 563  aarch64::GOTTableManager GOT(G);564  aarch64::PLTTableManager PLT(G, GOT);565  visitExistingEdges(G, GOT, PLT);566  return Error::success();567}568 569class MachOJITLinker_arm64 : public JITLinker<MachOJITLinker_arm64> {570  friend class JITLinker<MachOJITLinker_arm64>;571 572public:573  MachOJITLinker_arm64(std::unique_ptr<JITLinkContext> Ctx,574                       std::unique_ptr<LinkGraph> G,575                       PassConfiguration PassConfig)576      : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {}577 578private:579  Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {580    return aarch64::applyFixup(G, B, E, nullptr);581  }582 583  uint64_t NullValue = 0;584};585 586Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_arm64(587    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {588  auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer);589  if (!MachOObj)590    return MachOObj.takeError();591 592  auto Features = (*MachOObj)->getFeatures();593  if (!Features)594    return Features.takeError();595 596  return MachOLinkGraphBuilder_arm64(**MachOObj, std::move(SSP),597                                     std::move(*Features))598      .buildGraph();599}600 601static Error applyPACSigningToModInitPointers(LinkGraph &G) {602  assert(G.getTargetTriple().isArm64e() && "PAC signing only valid for arm64e");603 604  if (auto *ModInitSec = G.findSectionByName("__DATA,__mod_init_func")) {605    for (auto *B : ModInitSec->blocks()) {606      for (auto &E : B->edges()) {607        if (E.getKind() == aarch64::Pointer64) {608 609          // Check that we have room to encode pointer signing bits.610          if (E.getAddend() >> 32)611            return make_error<JITLinkError>(612                "In " + G.getName() + ", __mod_init_func pointer at " +613                formatv("{0:x}", B->getFixupAddress(E).getValue()) +614                " has data in high bits of addend (addend >= 2^32)");615 616          // Change edge to Pointer64Authenticated, encode signing:617          // key = asia, discriminator = 0, diversity = 0.618          Edge::AddendT SigningBits = 0x1ULL << 63;619          E.setKind(aarch64::Pointer64Authenticated);620          E.setAddend(E.getAddend() | SigningBits);621        }622      }623    }624  }625 626  return Error::success();627}628 629struct CompactUnwindTraits_MachO_arm64630    : public CompactUnwindTraits<CompactUnwindTraits_MachO_arm64,631                                 /* PointerSize = */ 8> {632  // FIXME: Reinstate once we no longer need the MSVC workaround. See633  //        FIXME for CompactUnwindTraits in CompactUnwindSupport.h.634  // constexpr static size_t PointerSize = 8;635 636  constexpr static endianness Endianness = endianness::little;637 638  constexpr static uint32_t EncodingModeMask = 0x0f000000;639  constexpr static uint32_t DWARFSectionOffsetMask = 0x00ffffff;640 641  using GOTManager = aarch64::GOTTableManager;642 643  static bool encodingSpecifiesDWARF(uint32_t Encoding) {644    constexpr uint32_t DWARFMode = 0x03000000;645    return (Encoding & EncodingModeMask) == DWARFMode;646  }647 648  static bool encodingCannotBeMerged(uint32_t Encoding) { return false; }649};650 651void link_MachO_arm64(std::unique_ptr<LinkGraph> G,652                      std::unique_ptr<JITLinkContext> Ctx) {653 654  PassConfiguration Config;655 656  if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) {657    // Add a mark-live pass.658    if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple()))659      Config.PrePrunePasses.push_back(std::move(MarkLive));660    else661      Config.PrePrunePasses.push_back(markAllSymbolsLive);662 663    // Add eh-frame passes.664    Config.PrePrunePasses.push_back(createEHFrameSplitterPass_MachO_arm64());665    Config.PrePrunePasses.push_back(createEHFrameEdgeFixerPass_MachO_arm64());666 667    // Create a compact-unwind manager for use in passes below.668    auto CompactUnwindMgr =669        std::make_shared<CompactUnwindManager<CompactUnwindTraits_MachO_arm64>>(670            orc::MachOCompactUnwindSectionName, orc::MachOUnwindInfoSectionName,671            orc::MachOEHFrameSectionName);672 673    // Add compact unwind prepare pass.674    Config.PrePrunePasses.push_back([CompactUnwindMgr](LinkGraph &G) {675      return CompactUnwindMgr->prepareForPrune(G);676    });677 678    // Resolve any external section start / end symbols.679    Config.PostAllocationPasses.push_back(680        createDefineExternalSectionStartAndEndSymbolsPass(681            identifyMachOSectionStartAndEndSymbols));682 683    // Add an in-place GOT/Stubs pass.684    Config.PostPrunePasses.push_back(buildTables_MachO_arm64);685 686    // If this is an arm64e graph then add pointer signing passes.687    if (G->getTargetTriple().isArm64e()) {688      Config.PostPrunePasses.push_back(applyPACSigningToModInitPointers);689      Config.PostPrunePasses.push_back(690          aarch64::createEmptyPointerSigningFunction);691      Config.PreFixupPasses.push_back(692          aarch64::lowerPointer64AuthEdgesToSigningFunction);693    }694 695    // Reserve unwind-info space.696    Config.PostPrunePasses.push_back([CompactUnwindMgr](LinkGraph &G) {697      return CompactUnwindMgr->processAndReserveUnwindInfo(G);698    });699 700    // Translate compact-unwind to unwind-info.701    Config.PreFixupPasses.push_back([CompactUnwindMgr](LinkGraph &G) {702      return CompactUnwindMgr->writeUnwindInfo(G);703    });704  }705 706  if (auto Err = Ctx->modifyPassConfig(*G, Config))707    return Ctx->notifyFailed(std::move(Err));708 709  // Construct a JITLinker and run the link function.710  MachOJITLinker_arm64::link(std::move(Ctx), std::move(G), std::move(Config));711}712 713LinkGraphPassFunction createEHFrameSplitterPass_MachO_arm64() {714  return DWARFRecordSectionSplitter(orc::MachOEHFrameSectionName);715}716 717LinkGraphPassFunction createEHFrameEdgeFixerPass_MachO_arm64() {718  return EHFrameEdgeFixer(orc::MachOEHFrameSectionName, aarch64::PointerSize,719                          aarch64::Pointer32, aarch64::Pointer64,720                          aarch64::Delta32, aarch64::Delta64,721                          aarch64::NegDelta32);722}723 724} // end namespace jitlink725} // end namespace llvm726