brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.4 KiB · cd2eed7 Raw
735 lines · cpp
1//===----- ELF_aarch64.cpp - JIT linker implementation for ELF/aarch64 ----===//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// ELF/aarch64 jit-link implementation.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h"14#include "llvm/BinaryFormat/ELF.h"15#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"16#include "llvm/ExecutionEngine/JITLink/aarch64.h"17#include "llvm/Object/ELFObjectFile.h"18#include "llvm/Support/Endian.h"19 20#include "DefineExternalSectionStartAndEndSymbols.h"21#include "EHFrameSupportImpl.h"22#include "ELFLinkGraphBuilder.h"23#include "JITLinkGeneric.h"24 25#define DEBUG_TYPE "jitlink"26 27using namespace llvm;28using namespace llvm::jitlink;29 30namespace {31 32constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";33 34class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {35  friend class JITLinker<ELFJITLinker_aarch64>;36 37public:38  ELFJITLinker_aarch64(std::unique_ptr<JITLinkContext> Ctx,39                       std::unique_ptr<LinkGraph> G,40                       PassConfiguration PassConfig)41      : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {42    if (shouldAddDefaultTargetPasses(getGraph().getTargetTriple()))43      getPassConfig().PostAllocationPasses.push_back(44          [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); });45  }46 47private:48  Symbol *GOTSymbol = nullptr;49 50  Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {51    return aarch64::applyFixup(G, B, E, GOTSymbol);52  }53 54  Error getOrCreateGOTSymbol(LinkGraph &G) {55    auto InteredGOTSymbolName =56        G.getSymbolStringPool()->intern(ELFGOTSymbolName);57 58    auto DefineExternalGOTSymbolIfPresent =59        createDefineExternalSectionStartAndEndSymbolsPass(60            [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {61              if (*Sym.getName() == ELFGOTSymbolName)62                if (auto *GOTSection = G.findSectionByName(63                        aarch64::GOTTableManager::getSectionName())) {64                  GOTSymbol = &Sym;65                  return {*GOTSection, true};66                }67              return {};68            });69 70    // Try to attach _GLOBAL_OFFSET_TABLE_ to the GOT if it's defined as an71    // external.72    if (auto Err = DefineExternalGOTSymbolIfPresent(G))73      return Err;74 75    // If we succeeded then we're done.76    if (GOTSymbol)77      return Error::success();78 79    // Otherwise look for a GOT section: If it already has a start symbol we'll80    // record it, otherwise we'll create our own.81    // If there's a GOT section but we didn't find an external GOT symbol...82    if (auto *GOTSection =83            G.findSectionByName(aarch64::GOTTableManager::getSectionName())) {84 85      // Check for an existing defined symbol.86      for (auto *Sym : GOTSection->symbols())87        if (Sym->getName() == InteredGOTSymbolName) {88          GOTSymbol = Sym;89          return Error::success();90        }91 92      // If there's no defined symbol then create one.93      SectionRange SR(*GOTSection);94      if (SR.empty())95        GOTSymbol =96            // FIXME: we should only do this once97            &G.addAbsoluteSymbol(InteredGOTSymbolName, orc::ExecutorAddr(), 0,98                                 Linkage::Strong, Scope::Local, true);99      else100        GOTSymbol =101            &G.addDefinedSymbol(*SR.getFirstBlock(), 0, InteredGOTSymbolName, 0,102                                Linkage::Strong, Scope::Local, false, true);103    }104 105    // If we still haven't found a GOT symbol then double check the externals.106    // We may have a GOT-relative reference but no GOT section, in which case107    // we just need to point the GOT symbol at some address in this graph.108    if (!GOTSymbol) {109      for (auto *Sym : G.external_symbols()) {110        if (*Sym->getName() == ELFGOTSymbolName) {111          auto Blocks = G.blocks();112          if (!Blocks.empty()) {113            G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());114            GOTSymbol = Sym;115            break;116          }117        }118      }119    }120 121    return Error::success();122  }123};124 125template <typename ELFT>126class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {127private:128  enum ELFAArch64RelocationKind : Edge::Kind {129    ELFCall26 = Edge::FirstRelocation,130    ELFLdrLo19,131    ELFAdrLo21,132    ELFAdrPage21,133    ELFAddAbs12,134    ELFLdSt8Abs12,135    ELFLdSt16Abs12,136    ELFLdSt32Abs12,137    ELFLdSt64Abs12,138    ELFLdSt128Abs12,139    ELFMovwAbsG0,140    ELFMovwAbsG1,141    ELFMovwAbsG2,142    ELFMovwAbsG3,143    ELFTstBr14,144    ELFCondBr19,145    ELFAbs32,146    ELFAbs64,147    ELFPrel32,148    ELFPrel64,149    ELFAdrGOTPage21,150    ELFLd64GOTLo12,151    ELFLd64GOTPAGELo15,152    ELFTLSDescAdrPage21,153    ELFTLSDescAddLo12,154    ELFTLSDescLd64Lo12,155    ELFTLSDescCall,156  };157 158  static Expected<ELFAArch64RelocationKind>159  getRelocationKind(const uint32_t Type) {160    using namespace aarch64;161    switch (Type) {162    case ELF::R_AARCH64_CALL26:163    case ELF::R_AARCH64_JUMP26:164      return ELFCall26;165    case ELF::R_AARCH64_LD_PREL_LO19:166      return ELFLdrLo19;167    case ELF::R_AARCH64_ADR_PREL_LO21:168      return ELFAdrLo21;169    case ELF::R_AARCH64_ADR_PREL_PG_HI21:170      return ELFAdrPage21;171    case ELF::R_AARCH64_ADD_ABS_LO12_NC:172      return ELFAddAbs12;173    case ELF::R_AARCH64_LDST8_ABS_LO12_NC:174      return ELFLdSt8Abs12;175    case ELF::R_AARCH64_LDST16_ABS_LO12_NC:176      return ELFLdSt16Abs12;177    case ELF::R_AARCH64_LDST32_ABS_LO12_NC:178      return ELFLdSt32Abs12;179    case ELF::R_AARCH64_LDST64_ABS_LO12_NC:180      return ELFLdSt64Abs12;181    case ELF::R_AARCH64_LDST128_ABS_LO12_NC:182      return ELFLdSt128Abs12;183    case ELF::R_AARCH64_MOVW_UABS_G0_NC:184      return ELFMovwAbsG0;185    case ELF::R_AARCH64_MOVW_UABS_G1_NC:186      return ELFMovwAbsG1;187    case ELF::R_AARCH64_MOVW_UABS_G2_NC:188      return ELFMovwAbsG2;189    case ELF::R_AARCH64_MOVW_UABS_G3:190      return ELFMovwAbsG3;191    case ELF::R_AARCH64_TSTBR14:192      return ELFTstBr14;193    case ELF::R_AARCH64_CONDBR19:194      return ELFCondBr19;195    case ELF::R_AARCH64_ABS32:196      return ELFAbs32;197    case ELF::R_AARCH64_ABS64:198      return ELFAbs64;199    case ELF::R_AARCH64_PREL32:200      return ELFPrel32;201    case ELF::R_AARCH64_PREL64:202      return ELFPrel64;203    case ELF::R_AARCH64_ADR_GOT_PAGE:204      return ELFAdrGOTPage21;205    case ELF::R_AARCH64_LD64_GOT_LO12_NC:206      return ELFLd64GOTLo12;207    case ELF::R_AARCH64_LD64_GOTPAGE_LO15:208      return ELFLd64GOTPAGELo15;209    case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:210      return ELFTLSDescAdrPage21;211    case ELF::R_AARCH64_TLSDESC_ADD_LO12:212      return ELFTLSDescAddLo12;213    case ELF::R_AARCH64_TLSDESC_LD64_LO12:214      return ELFTLSDescLd64Lo12;215    case ELF::R_AARCH64_TLSDESC_CALL:216      return ELFTLSDescCall;217    }218 219    return make_error<JITLinkError>(220        "Unsupported aarch64 relocation:" + formatv("{0:d}: ", Type) +221        object::getELFRelocationTypeName(ELF::EM_AARCH64, Type));222  }223 224  Error addRelocations() override {225    LLVM_DEBUG(dbgs() << "Processing relocations:\n");226 227    using Base = ELFLinkGraphBuilder<ELFT>;228    using Self = ELFLinkGraphBuilder_aarch64<ELFT>;229    for (const auto &RelSect : Base::Sections)230      if (Error Err = Base::forEachRelaRelocation(RelSect, this,231                                                  &Self::addSingleRelocation))232        return Err;233 234    return Error::success();235  }236 237  Error addSingleRelocation(const typename ELFT::Rela &Rel,238                            const typename ELFT::Shdr &FixupSect,239                            Block &BlockToFix) {240    using support::ulittle32_t;241    using Base = ELFLinkGraphBuilder<ELFT>;242 243    uint32_t SymbolIndex = Rel.getSymbol(false);244    auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);245    if (!ObjSymbol)246      return ObjSymbol.takeError();247 248    Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);249    if (!GraphSymbol)250      return make_error<StringError>(251          formatv("Could not find symbol at given index, did you add it to "252                  "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",253                  SymbolIndex, (*ObjSymbol)->st_shndx,254                  Base::GraphSymbols.size()),255          inconvertibleErrorCode());256 257    uint32_t Type = Rel.getType(false);258    Expected<ELFAArch64RelocationKind> RelocKind = getRelocationKind(Type);259    if (!RelocKind)260      return RelocKind.takeError();261 262    int64_t Addend = Rel.r_addend;263    orc::ExecutorAddr FixupAddress =264        orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;265    Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();266 267    // Get a pointer to the fixup content.268    const void *FixupContent = BlockToFix.getContent().data() +269                               (FixupAddress - BlockToFix.getAddress());270 271    Edge::Kind Kind = Edge::Invalid;272 273    switch (*RelocKind) {274    case ELFCall26: {275      Kind = aarch64::Branch26PCRel;276      break;277    }278    case ELFLdrLo19: {279      uint32_t Instr = *(const ulittle32_t *)FixupContent;280      if (!aarch64::isLDRLiteral(Instr))281        return make_error<JITLinkError>(282            "R_AARCH64_LDR_PREL_LO19 target is not an LDR Literal instruction");283 284      Kind = aarch64::LDRLiteral19;285      break;286    }287    case ELFAdrLo21: {288      uint32_t Instr = *(const ulittle32_t *)FixupContent;289      if (!aarch64::isADR(Instr))290        return make_error<JITLinkError>(291            "R_AARCH64_ADR_PREL_LO21 target is not an ADR instruction");292 293      Kind = aarch64::ADRLiteral21;294      break;295    }296    case ELFAdrPage21: {297      Kind = aarch64::Page21;298      break;299    }300    case ELFAddAbs12: {301      Kind = aarch64::PageOffset12;302      break;303    }304    case ELFLdSt8Abs12: {305      uint32_t Instr = *(const ulittle32_t *)FixupContent;306      if (!aarch64::isLoadStoreImm12(Instr) ||307          aarch64::getPageOffset12Shift(Instr) != 0)308        return make_error<JITLinkError>(309            "R_AARCH64_LDST8_ABS_LO12_NC target is not a "310            "LDRB/STRB (imm12) instruction");311 312      Kind = aarch64::PageOffset12;313      break;314    }315    case ELFLdSt16Abs12: {316      uint32_t Instr = *(const ulittle32_t *)FixupContent;317      if (!aarch64::isLoadStoreImm12(Instr) ||318          aarch64::getPageOffset12Shift(Instr) != 1)319        return make_error<JITLinkError>(320            "R_AARCH64_LDST16_ABS_LO12_NC target is not a "321            "LDRH/STRH (imm12) instruction");322 323      Kind = aarch64::PageOffset12;324      break;325    }326    case ELFLdSt32Abs12: {327      uint32_t Instr = *(const ulittle32_t *)FixupContent;328      if (!aarch64::isLoadStoreImm12(Instr) ||329          aarch64::getPageOffset12Shift(Instr) != 2)330        return make_error<JITLinkError>(331            "R_AARCH64_LDST32_ABS_LO12_NC target is not a "332            "LDR/STR (imm12, 32 bit) instruction");333 334      Kind = aarch64::PageOffset12;335      break;336    }337    case ELFLdSt64Abs12: {338      uint32_t Instr = *(const ulittle32_t *)FixupContent;339      if (!aarch64::isLoadStoreImm12(Instr) ||340          aarch64::getPageOffset12Shift(Instr) != 3)341        return make_error<JITLinkError>(342            "R_AARCH64_LDST64_ABS_LO12_NC target is not a "343            "LDR/STR (imm12, 64 bit) instruction");344 345      Kind = aarch64::PageOffset12;346      break;347    }348    case ELFLdSt128Abs12: {349      uint32_t Instr = *(const ulittle32_t *)FixupContent;350      if (!aarch64::isLoadStoreImm12(Instr) ||351          aarch64::getPageOffset12Shift(Instr) != 4)352        return make_error<JITLinkError>(353            "R_AARCH64_LDST128_ABS_LO12_NC target is not a "354            "LDR/STR (imm12, 128 bit) instruction");355 356      Kind = aarch64::PageOffset12;357      break;358    }359    case ELFMovwAbsG0: {360      uint32_t Instr = *(const ulittle32_t *)FixupContent;361      if (!aarch64::isMoveWideImm16(Instr) ||362          aarch64::getMoveWide16Shift(Instr) != 0)363        return make_error<JITLinkError>(364            "R_AARCH64_MOVW_UABS_G0_NC target is not a "365            "MOVK/MOVZ (imm16, LSL #0) instruction");366 367      Kind = aarch64::MoveWide16;368      break;369    }370    case ELFMovwAbsG1: {371      uint32_t Instr = *(const ulittle32_t *)FixupContent;372      if (!aarch64::isMoveWideImm16(Instr) ||373          aarch64::getMoveWide16Shift(Instr) != 16)374        return make_error<JITLinkError>(375            "R_AARCH64_MOVW_UABS_G1_NC target is not a "376            "MOVK/MOVZ (imm16, LSL #16) instruction");377 378      Kind = aarch64::MoveWide16;379      break;380    }381    case ELFMovwAbsG2: {382      uint32_t Instr = *(const ulittle32_t *)FixupContent;383      if (!aarch64::isMoveWideImm16(Instr) ||384          aarch64::getMoveWide16Shift(Instr) != 32)385        return make_error<JITLinkError>(386            "R_AARCH64_MOVW_UABS_G2_NC target is not a "387            "MOVK/MOVZ (imm16, LSL #32) instruction");388 389      Kind = aarch64::MoveWide16;390      break;391    }392    case ELFMovwAbsG3: {393      uint32_t Instr = *(const ulittle32_t *)FixupContent;394      if (!aarch64::isMoveWideImm16(Instr) ||395          aarch64::getMoveWide16Shift(Instr) != 48)396        return make_error<JITLinkError>(397            "R_AARCH64_MOVW_UABS_G3 target is not a "398            "MOVK/MOVZ (imm16, LSL #48) instruction");399 400      Kind = aarch64::MoveWide16;401      break;402    }403    case ELFTstBr14: {404      uint32_t Instr = *(const ulittle32_t *)FixupContent;405      if (!aarch64::isTestAndBranchImm14(Instr))406        return make_error<JITLinkError>("R_AARCH64_TSTBR14 target is not a "407                                        "test and branch instruction");408 409      Kind = aarch64::TestAndBranch14PCRel;410      break;411    }412    case ELFCondBr19: {413      uint32_t Instr = *(const ulittle32_t *)FixupContent;414      if (!aarch64::isCondBranchImm19(Instr) &&415          !aarch64::isCompAndBranchImm19(Instr))416        return make_error<JITLinkError>("R_AARCH64_CONDBR19 target is not a "417                                        "conditional branch instruction");418 419      Kind = aarch64::CondBranch19PCRel;420      break;421    }422    case ELFAbs32: {423      Kind = aarch64::Pointer32;424      break;425    }426    case ELFAbs64: {427      Kind = aarch64::Pointer64;428      break;429    }430    case ELFPrel32: {431      Kind = aarch64::Delta32;432      break;433    }434    case ELFPrel64: {435      Kind = aarch64::Delta64;436      break;437    }438    case ELFAdrGOTPage21: {439      Kind = aarch64::RequestGOTAndTransformToPage21;440      break;441    }442    case ELFLd64GOTLo12: {443      Kind = aarch64::RequestGOTAndTransformToPageOffset12;444      break;445    }446    case ELFLd64GOTPAGELo15: {447      Kind = aarch64::RequestGOTAndTransformToPageOffset15;448      break;449    }450    case ELFTLSDescAdrPage21: {451      Kind = aarch64::RequestTLSDescEntryAndTransformToPage21;452      break;453    }454    case ELFTLSDescAddLo12:455    case ELFTLSDescLd64Lo12: {456      Kind = aarch64::RequestTLSDescEntryAndTransformToPageOffset12;457      break;458    }459    case ELFTLSDescCall: {460      return Error::success();461    }462    };463 464    Edge GE(Kind, Offset, *GraphSymbol, Addend);465    LLVM_DEBUG({466      dbgs() << "    ";467      printEdge(dbgs(), BlockToFix, GE, aarch64::getEdgeKindName(Kind));468      dbgs() << "\n";469    });470 471    BlockToFix.addEdge(std::move(GE));472 473    return Error::success();474  }475 476  /// Return the string name of the given ELF aarch64 edge kind.477  const char *getELFAArch64RelocationKindName(Edge::Kind R) {478    switch (R) {479    case ELFCall26:480      return "ELFCall26";481    case ELFAdrPage21:482      return "ELFAdrPage21";483    case ELFAddAbs12:484      return "ELFAddAbs12";485    case ELFLdSt8Abs12:486      return "ELFLdSt8Abs12";487    case ELFLdSt16Abs12:488      return "ELFLdSt16Abs12";489    case ELFLdSt32Abs12:490      return "ELFLdSt32Abs12";491    case ELFLdSt64Abs12:492      return "ELFLdSt64Abs12";493    case ELFLdSt128Abs12:494      return "ELFLdSt128Abs12";495    case ELFMovwAbsG0:496      return "ELFMovwAbsG0";497    case ELFMovwAbsG1:498      return "ELFMovwAbsG1";499    case ELFMovwAbsG2:500      return "ELFMovwAbsG2";501    case ELFMovwAbsG3:502      return "ELFMovwAbsG3";503    case ELFAbs32:504      return "ELFAbs32";505    case ELFAbs64:506      return "ELFAbs64";507    case ELFPrel32:508      return "ELFPrel32";509    case ELFPrel64:510      return "ELFPrel64";511    case ELFAdrGOTPage21:512      return "ELFAdrGOTPage21";513    case ELFLd64GOTLo12:514      return "ELFLd64GOTLo12";515    case ELFLd64GOTPAGELo15:516      return "ELFLd64GOTPAGELo15";517    case ELFTLSDescAdrPage21:518      return "ELFTLSDescAdrPage21";519    case ELFTLSDescAddLo12:520      return "ELFTLSDescAddLo12";521    case ELFTLSDescLd64Lo12:522      return "ELFTLSDescLd64Lo12";523    case ELFTLSDescCall:524      return "ELFTLSDescCall";525    default:526      return getGenericEdgeKindName(R);527    }528  }529 530public:531  ELFLinkGraphBuilder_aarch64(StringRef FileName,532                              const object::ELFFile<ELFT> &Obj,533                              std::shared_ptr<orc::SymbolStringPool> SSP,534                              Triple TT, SubtargetFeatures Features)535 536      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),537                                  std::move(Features), FileName,538                                  aarch64::getEdgeKindName) {}539};540 541// TLS Info Builder.542class TLSInfoTableManager_ELF_aarch64543    : public TableManager<TLSInfoTableManager_ELF_aarch64> {544public:545  static StringRef getSectionName() { return "$__TLSINFO"; }546 547  static const uint8_t TLSInfoEntryContent[16];548 549  bool visitEdge(LinkGraph &G, Block *B, Edge &E) { return false; }550 551  Symbol &createEntry(LinkGraph &G, Symbol &Target) {552    // the TLS Info entry's key value will be written by the fixTLVSectionByName553    // pass, so create mutable content.554    auto &TLSInfoEntry = G.createMutableContentBlock(555        getTLSInfoSection(G), G.allocateContent(getTLSInfoEntryContent()),556        orc::ExecutorAddr(), 8, 0);557    TLSInfoEntry.addEdge(aarch64::Pointer64, 8, Target, 0);558    return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false);559  }560 561private:562  Section &getTLSInfoSection(LinkGraph &G) {563    if (!TLSInfoTable)564      TLSInfoTable = &G.createSection(getSectionName(), orc::MemProt::Read);565    return *TLSInfoTable;566  }567 568  ArrayRef<char> getTLSInfoEntryContent() const {569    return {reinterpret_cast<const char *>(TLSInfoEntryContent),570            sizeof(TLSInfoEntryContent)};571  }572 573  Section *TLSInfoTable = nullptr;574};575 576const uint8_t TLSInfoTableManager_ELF_aarch64::TLSInfoEntryContent[16] = {577    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */578    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /*data address*/579};580 581// TLS Descriptor Builder.582class TLSDescTableManager_ELF_aarch64583    : public TableManager<TLSDescTableManager_ELF_aarch64> {584public:585  TLSDescTableManager_ELF_aarch64(586      TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager)587      : TLSInfoTableManager(TLSInfoTableManager) {}588 589  static StringRef getSectionName() { return "$__TLSDESC"; }590 591  static const uint8_t TLSDescEntryContent[16];592 593  bool visitEdge(LinkGraph &G, Block *B, Edge &E) {594    Edge::Kind KindToSet = Edge::Invalid;595    switch (E.getKind()) {596    case aarch64::RequestTLSDescEntryAndTransformToPage21: {597      KindToSet = aarch64::Page21;598      break;599    }600    case aarch64::RequestTLSDescEntryAndTransformToPageOffset12: {601      KindToSet = aarch64::PageOffset12;602      break;603    }604    default:605      return false;606    }607    assert(KindToSet != Edge::Invalid &&608           "Fell through switch, but no new kind to set");609    DEBUG_WITH_TYPE("jitlink", {610      dbgs() << "  Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "611             << B->getFixupAddress(E) << " (" << B->getAddress() << " + "612             << formatv("{0:x}", E.getOffset()) << ")\n";613    });614    E.setKind(KindToSet);615    E.setTarget(getEntryForTarget(G, E.getTarget()));616    return true;617  }618 619  Symbol &createEntry(LinkGraph &G, Symbol &Target) {620    auto &EntryBlock =621        G.createContentBlock(getTLSDescSection(G), getTLSDescBlockContent(),622                             orc::ExecutorAddr(), 8, 0);623    EntryBlock.addEdge(aarch64::Pointer64, 0, getTLSDescResolver(G), 0);624    EntryBlock.addEdge(aarch64::Pointer64, 8,625                       TLSInfoTableManager.getEntryForTarget(G, Target), 0);626    return G.addAnonymousSymbol(EntryBlock, 0, 8, false, false);627  }628 629private:630  Section &getTLSDescSection(LinkGraph &G) {631    if (!GOTSection)632      GOTSection = &G.createSection(getSectionName(), orc::MemProt::Read);633    return *GOTSection;634  }635 636  Symbol &getTLSDescResolver(LinkGraph &G) {637    if (!TLSDescResolver)638      TLSDescResolver = &G.addExternalSymbol("__tlsdesc_resolver", 8, false);639    return *TLSDescResolver;640  }641 642  ArrayRef<char> getTLSDescBlockContent() {643    return {reinterpret_cast<const char *>(TLSDescEntryContent),644            sizeof(TLSDescEntryContent)};645  }646 647  Section *GOTSection = nullptr;648  Symbol *TLSDescResolver = nullptr;649  TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager;650};651 652const uint8_t TLSDescTableManager_ELF_aarch64::TLSDescEntryContent[16] = {653    0x00, 0x00, 0x00, 0x00,654    0x00, 0x00, 0x00, 0x00, /*resolver function pointer*/655    0x00, 0x00, 0x00, 0x00,656    0x00, 0x00, 0x00, 0x00 /*pointer to tls info*/657};658 659Error buildTables_ELF_aarch64(LinkGraph &G) {660  LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");661 662  aarch64::GOTTableManager GOT(G);663  aarch64::PLTTableManager PLT(G, GOT);664  TLSInfoTableManager_ELF_aarch64 TLSInfo;665  TLSDescTableManager_ELF_aarch64 TLSDesc(TLSInfo);666  visitExistingEdges(G, GOT, PLT, TLSDesc, TLSInfo);667  return Error::success();668}669 670} // namespace671 672namespace llvm {673namespace jitlink {674 675Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch64(676    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {677  LLVM_DEBUG({678    dbgs() << "Building jitlink graph for new input "679           << ObjectBuffer.getBufferIdentifier() << "...\n";680  });681 682  auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer);683  if (!ELFObj)684    return ELFObj.takeError();685 686  auto Features = (*ELFObj)->getFeatures();687  if (!Features)688    return Features.takeError();689 690  assert((*ELFObj)->getArch() == Triple::aarch64 &&691         "Only AArch64 (little endian) is supported for now");692 693  auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);694  return ELFLinkGraphBuilder_aarch64<object::ELF64LE>(695             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),696             (*ELFObj)->makeTriple(), std::move(*Features))697      .buildGraph();698}699 700void link_ELF_aarch64(std::unique_ptr<LinkGraph> G,701                      std::unique_ptr<JITLinkContext> Ctx) {702  PassConfiguration Config;703  const Triple &TT = G->getTargetTriple();704  if (Ctx->shouldAddDefaultTargetPasses(TT)) {705    // Add eh-frame passes.706    Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame"));707    Config.PrePrunePasses.push_back(EHFrameEdgeFixer(708        ".eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64,709        aarch64::Delta32, aarch64::Delta64, aarch64::NegDelta32));710    Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame"));711 712    // Add a mark-live pass.713    if (auto MarkLive = Ctx->getMarkLivePass(TT))714      Config.PrePrunePasses.push_back(std::move(MarkLive));715    else716      Config.PrePrunePasses.push_back(markAllSymbolsLive);717 718    // Resolve any external section start / end symbols.719    Config.PostAllocationPasses.push_back(720        createDefineExternalSectionStartAndEndSymbolsPass(721            identifyELFSectionStartAndEndSymbols));722 723    // Add an in-place GOT/TLS/Stubs build pass.724    Config.PostPrunePasses.push_back(buildTables_ELF_aarch64);725  }726 727  if (auto Err = Ctx->modifyPassConfig(*G, Config))728    return Ctx->notifyFailed(std::move(Err));729 730  ELFJITLinker_aarch64::link(std::move(Ctx), std::move(G), std::move(Config));731}732 733} // namespace jitlink734} // namespace llvm735