1349cc55cSDimitry Andric //===----- ELF_aarch64.cpp - JIT linker implementation for ELF/aarch64 ----===// 2349cc55cSDimitry Andric // 3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6349cc55cSDimitry Andric // 7349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8349cc55cSDimitry Andric // 9349cc55cSDimitry Andric // ELF/aarch64 jit-link implementation. 10349cc55cSDimitry Andric // 11349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 12349cc55cSDimitry Andric 13349cc55cSDimitry Andric #include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h" 14*81ad6265SDimitry Andric #include "EHFrameSupportImpl.h" 15349cc55cSDimitry Andric #include "ELFLinkGraphBuilder.h" 16349cc55cSDimitry Andric #include "JITLinkGeneric.h" 17349cc55cSDimitry Andric #include "llvm/BinaryFormat/ELF.h" 18*81ad6265SDimitry Andric #include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h" 19349cc55cSDimitry Andric #include "llvm/ExecutionEngine/JITLink/aarch64.h" 20349cc55cSDimitry Andric #include "llvm/Object/ELFObjectFile.h" 21*81ad6265SDimitry Andric #include "llvm/Support/Endian.h" 22349cc55cSDimitry Andric 23349cc55cSDimitry Andric #define DEBUG_TYPE "jitlink" 24349cc55cSDimitry Andric 25349cc55cSDimitry Andric using namespace llvm; 26349cc55cSDimitry Andric using namespace llvm::jitlink; 27349cc55cSDimitry Andric 28*81ad6265SDimitry Andric namespace { 29349cc55cSDimitry Andric 30349cc55cSDimitry Andric class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> { 31349cc55cSDimitry Andric friend class JITLinker<ELFJITLinker_aarch64>; 32349cc55cSDimitry Andric 33349cc55cSDimitry Andric public: 34349cc55cSDimitry Andric ELFJITLinker_aarch64(std::unique_ptr<JITLinkContext> Ctx, 35349cc55cSDimitry Andric std::unique_ptr<LinkGraph> G, 36349cc55cSDimitry Andric PassConfiguration PassConfig) 37349cc55cSDimitry Andric : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {} 38349cc55cSDimitry Andric 39349cc55cSDimitry Andric private: 40349cc55cSDimitry Andric Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const { 41*81ad6265SDimitry Andric return aarch64::applyFixup(G, B, E); 42349cc55cSDimitry Andric } 43349cc55cSDimitry Andric }; 44349cc55cSDimitry Andric 45349cc55cSDimitry Andric template <typename ELFT> 46349cc55cSDimitry Andric class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> { 47349cc55cSDimitry Andric private: 48*81ad6265SDimitry Andric enum ELFAArch64RelocationKind : Edge::Kind { 49*81ad6265SDimitry Andric ELFCall26 = Edge::FirstRelocation, 50*81ad6265SDimitry Andric ELFAdrPage21, 51*81ad6265SDimitry Andric ELFAddAbs12, 52*81ad6265SDimitry Andric ELFLdSt8Abs12, 53*81ad6265SDimitry Andric ELFLdSt16Abs12, 54*81ad6265SDimitry Andric ELFLdSt32Abs12, 55*81ad6265SDimitry Andric ELFLdSt64Abs12, 56*81ad6265SDimitry Andric ELFLdSt128Abs12, 57*81ad6265SDimitry Andric ELFMovwAbsG0, 58*81ad6265SDimitry Andric ELFMovwAbsG1, 59*81ad6265SDimitry Andric ELFMovwAbsG2, 60*81ad6265SDimitry Andric ELFMovwAbsG3, 61*81ad6265SDimitry Andric ELFAbs64, 62*81ad6265SDimitry Andric ELFPrel32, 63*81ad6265SDimitry Andric ELFPrel64, 64*81ad6265SDimitry Andric ELFAdrGOTPage21, 65*81ad6265SDimitry Andric ELFLd64GOTLo12, 66*81ad6265SDimitry Andric }; 67*81ad6265SDimitry Andric 68*81ad6265SDimitry Andric static Expected<ELFAArch64RelocationKind> 69349cc55cSDimitry Andric getRelocationKind(const uint32_t Type) { 70349cc55cSDimitry Andric using namespace aarch64; 71349cc55cSDimitry Andric switch (Type) { 72349cc55cSDimitry Andric case ELF::R_AARCH64_CALL26: 73*81ad6265SDimitry Andric case ELF::R_AARCH64_JUMP26: 74*81ad6265SDimitry Andric return ELFCall26; 75*81ad6265SDimitry Andric case ELF::R_AARCH64_ADR_PREL_PG_HI21: 76*81ad6265SDimitry Andric return ELFAdrPage21; 77*81ad6265SDimitry Andric case ELF::R_AARCH64_ADD_ABS_LO12_NC: 78*81ad6265SDimitry Andric return ELFAddAbs12; 79*81ad6265SDimitry Andric case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 80*81ad6265SDimitry Andric return ELFLdSt8Abs12; 81*81ad6265SDimitry Andric case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 82*81ad6265SDimitry Andric return ELFLdSt16Abs12; 83*81ad6265SDimitry Andric case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 84*81ad6265SDimitry Andric return ELFLdSt32Abs12; 85*81ad6265SDimitry Andric case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 86*81ad6265SDimitry Andric return ELFLdSt64Abs12; 87*81ad6265SDimitry Andric case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 88*81ad6265SDimitry Andric return ELFLdSt128Abs12; 89*81ad6265SDimitry Andric case ELF::R_AARCH64_MOVW_UABS_G0_NC: 90*81ad6265SDimitry Andric return ELFMovwAbsG0; 91*81ad6265SDimitry Andric case ELF::R_AARCH64_MOVW_UABS_G1_NC: 92*81ad6265SDimitry Andric return ELFMovwAbsG1; 93*81ad6265SDimitry Andric case ELF::R_AARCH64_MOVW_UABS_G2_NC: 94*81ad6265SDimitry Andric return ELFMovwAbsG2; 95*81ad6265SDimitry Andric case ELF::R_AARCH64_MOVW_UABS_G3: 96*81ad6265SDimitry Andric return ELFMovwAbsG3; 97*81ad6265SDimitry Andric case ELF::R_AARCH64_ABS64: 98*81ad6265SDimitry Andric return ELFAbs64; 99*81ad6265SDimitry Andric case ELF::R_AARCH64_PREL32: 100*81ad6265SDimitry Andric return ELFPrel32; 101*81ad6265SDimitry Andric case ELF::R_AARCH64_PREL64: 102*81ad6265SDimitry Andric return ELFPrel64; 103*81ad6265SDimitry Andric case ELF::R_AARCH64_ADR_GOT_PAGE: 104*81ad6265SDimitry Andric return ELFAdrGOTPage21; 105*81ad6265SDimitry Andric case ELF::R_AARCH64_LD64_GOT_LO12_NC: 106*81ad6265SDimitry Andric return ELFLd64GOTLo12; 107349cc55cSDimitry Andric } 108349cc55cSDimitry Andric 109*81ad6265SDimitry Andric return make_error<JITLinkError>( 110*81ad6265SDimitry Andric "Unsupported aarch64 relocation:" + formatv("{0:d}: ", Type) + 111*81ad6265SDimitry Andric object::getELFRelocationTypeName(ELF::EM_AARCH64, Type)); 112349cc55cSDimitry Andric } 113349cc55cSDimitry Andric 114349cc55cSDimitry Andric Error addRelocations() override { 115349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Processing relocations:\n"); 116349cc55cSDimitry Andric 117349cc55cSDimitry Andric using Base = ELFLinkGraphBuilder<ELFT>; 118349cc55cSDimitry Andric using Self = ELFLinkGraphBuilder_aarch64<ELFT>; 119349cc55cSDimitry Andric for (const auto &RelSect : Base::Sections) 120349cc55cSDimitry Andric if (Error Err = Base::forEachRelocation(RelSect, this, 121349cc55cSDimitry Andric &Self::addSingleRelocation)) 122349cc55cSDimitry Andric return Err; 123349cc55cSDimitry Andric 124349cc55cSDimitry Andric return Error::success(); 125349cc55cSDimitry Andric } 126349cc55cSDimitry Andric 127349cc55cSDimitry Andric Error addSingleRelocation(const typename ELFT::Rela &Rel, 128349cc55cSDimitry Andric const typename ELFT::Shdr &FixupSect, 12904eeddc0SDimitry Andric Block &BlockToFix) { 130*81ad6265SDimitry Andric using support::ulittle32_t; 131349cc55cSDimitry Andric using Base = ELFLinkGraphBuilder<ELFT>; 132349cc55cSDimitry Andric 133349cc55cSDimitry Andric uint32_t SymbolIndex = Rel.getSymbol(false); 134349cc55cSDimitry Andric auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec); 135349cc55cSDimitry Andric if (!ObjSymbol) 136349cc55cSDimitry Andric return ObjSymbol.takeError(); 137349cc55cSDimitry Andric 138349cc55cSDimitry Andric Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex); 139349cc55cSDimitry Andric if (!GraphSymbol) 140349cc55cSDimitry Andric return make_error<StringError>( 141349cc55cSDimitry Andric formatv("Could not find symbol at given index, did you add it to " 142349cc55cSDimitry Andric "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}", 143349cc55cSDimitry Andric SymbolIndex, (*ObjSymbol)->st_shndx, 144349cc55cSDimitry Andric Base::GraphSymbols.size()), 145349cc55cSDimitry Andric inconvertibleErrorCode()); 146349cc55cSDimitry Andric 147349cc55cSDimitry Andric uint32_t Type = Rel.getType(false); 148*81ad6265SDimitry Andric Expected<ELFAArch64RelocationKind> RelocKind = getRelocationKind(Type); 149*81ad6265SDimitry Andric if (!RelocKind) 150*81ad6265SDimitry Andric return RelocKind.takeError(); 151349cc55cSDimitry Andric 152349cc55cSDimitry Andric int64_t Addend = Rel.r_addend; 15304eeddc0SDimitry Andric orc::ExecutorAddr FixupAddress = 15404eeddc0SDimitry Andric orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset; 15504eeddc0SDimitry Andric Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); 156*81ad6265SDimitry Andric 157*81ad6265SDimitry Andric // Get a pointer to the fixup content. 158*81ad6265SDimitry Andric const void *FixupContent = BlockToFix.getContent().data() + 159*81ad6265SDimitry Andric (FixupAddress - BlockToFix.getAddress()); 160*81ad6265SDimitry Andric 161*81ad6265SDimitry Andric Edge::Kind Kind = Edge::Invalid; 162*81ad6265SDimitry Andric 163*81ad6265SDimitry Andric switch (*RelocKind) { 164*81ad6265SDimitry Andric case ELFCall26: { 165*81ad6265SDimitry Andric Kind = aarch64::Branch26; 166*81ad6265SDimitry Andric break; 167*81ad6265SDimitry Andric } 168*81ad6265SDimitry Andric case ELFAdrPage21: { 169*81ad6265SDimitry Andric Kind = aarch64::Page21; 170*81ad6265SDimitry Andric break; 171*81ad6265SDimitry Andric } 172*81ad6265SDimitry Andric case ELFAddAbs12: { 173*81ad6265SDimitry Andric Kind = aarch64::PageOffset12; 174*81ad6265SDimitry Andric break; 175*81ad6265SDimitry Andric } 176*81ad6265SDimitry Andric case ELFLdSt8Abs12: { 177*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 178*81ad6265SDimitry Andric if (!aarch64::isLoadStoreImm12(Instr) || 179*81ad6265SDimitry Andric aarch64::getPageOffset12Shift(Instr) != 0) 180*81ad6265SDimitry Andric return make_error<JITLinkError>( 181*81ad6265SDimitry Andric "R_AARCH64_LDST8_ABS_LO12_NC target is not a " 182*81ad6265SDimitry Andric "LDRB/STRB (imm12) instruction"); 183*81ad6265SDimitry Andric 184*81ad6265SDimitry Andric Kind = aarch64::PageOffset12; 185*81ad6265SDimitry Andric break; 186*81ad6265SDimitry Andric } 187*81ad6265SDimitry Andric case ELFLdSt16Abs12: { 188*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 189*81ad6265SDimitry Andric if (!aarch64::isLoadStoreImm12(Instr) || 190*81ad6265SDimitry Andric aarch64::getPageOffset12Shift(Instr) != 1) 191*81ad6265SDimitry Andric return make_error<JITLinkError>( 192*81ad6265SDimitry Andric "R_AARCH64_LDST16_ABS_LO12_NC target is not a " 193*81ad6265SDimitry Andric "LDRH/STRH (imm12) instruction"); 194*81ad6265SDimitry Andric 195*81ad6265SDimitry Andric Kind = aarch64::PageOffset12; 196*81ad6265SDimitry Andric break; 197*81ad6265SDimitry Andric } 198*81ad6265SDimitry Andric case ELFLdSt32Abs12: { 199*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 200*81ad6265SDimitry Andric if (!aarch64::isLoadStoreImm12(Instr) || 201*81ad6265SDimitry Andric aarch64::getPageOffset12Shift(Instr) != 2) 202*81ad6265SDimitry Andric return make_error<JITLinkError>( 203*81ad6265SDimitry Andric "R_AARCH64_LDST32_ABS_LO12_NC target is not a " 204*81ad6265SDimitry Andric "LDR/STR (imm12, 32 bit) instruction"); 205*81ad6265SDimitry Andric 206*81ad6265SDimitry Andric Kind = aarch64::PageOffset12; 207*81ad6265SDimitry Andric break; 208*81ad6265SDimitry Andric } 209*81ad6265SDimitry Andric case ELFLdSt64Abs12: { 210*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 211*81ad6265SDimitry Andric if (!aarch64::isLoadStoreImm12(Instr) || 212*81ad6265SDimitry Andric aarch64::getPageOffset12Shift(Instr) != 3) 213*81ad6265SDimitry Andric return make_error<JITLinkError>( 214*81ad6265SDimitry Andric "R_AARCH64_LDST64_ABS_LO12_NC target is not a " 215*81ad6265SDimitry Andric "LDR/STR (imm12, 64 bit) instruction"); 216*81ad6265SDimitry Andric 217*81ad6265SDimitry Andric Kind = aarch64::PageOffset12; 218*81ad6265SDimitry Andric break; 219*81ad6265SDimitry Andric } 220*81ad6265SDimitry Andric case ELFLdSt128Abs12: { 221*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 222*81ad6265SDimitry Andric if (!aarch64::isLoadStoreImm12(Instr) || 223*81ad6265SDimitry Andric aarch64::getPageOffset12Shift(Instr) != 4) 224*81ad6265SDimitry Andric return make_error<JITLinkError>( 225*81ad6265SDimitry Andric "R_AARCH64_LDST128_ABS_LO12_NC target is not a " 226*81ad6265SDimitry Andric "LDR/STR (imm12, 128 bit) instruction"); 227*81ad6265SDimitry Andric 228*81ad6265SDimitry Andric Kind = aarch64::PageOffset12; 229*81ad6265SDimitry Andric break; 230*81ad6265SDimitry Andric } 231*81ad6265SDimitry Andric case ELFMovwAbsG0: { 232*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 233*81ad6265SDimitry Andric if (!aarch64::isMoveWideImm16(Instr) || 234*81ad6265SDimitry Andric aarch64::getMoveWide16Shift(Instr) != 0) 235*81ad6265SDimitry Andric return make_error<JITLinkError>( 236*81ad6265SDimitry Andric "R_AARCH64_MOVW_UABS_G0_NC target is not a " 237*81ad6265SDimitry Andric "MOVK/MOVZ (imm16, LSL #0) instruction"); 238*81ad6265SDimitry Andric 239*81ad6265SDimitry Andric Kind = aarch64::MoveWide16; 240*81ad6265SDimitry Andric break; 241*81ad6265SDimitry Andric } 242*81ad6265SDimitry Andric case ELFMovwAbsG1: { 243*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 244*81ad6265SDimitry Andric if (!aarch64::isMoveWideImm16(Instr) || 245*81ad6265SDimitry Andric aarch64::getMoveWide16Shift(Instr) != 16) 246*81ad6265SDimitry Andric return make_error<JITLinkError>( 247*81ad6265SDimitry Andric "R_AARCH64_MOVW_UABS_G1_NC target is not a " 248*81ad6265SDimitry Andric "MOVK/MOVZ (imm16, LSL #16) instruction"); 249*81ad6265SDimitry Andric 250*81ad6265SDimitry Andric Kind = aarch64::MoveWide16; 251*81ad6265SDimitry Andric break; 252*81ad6265SDimitry Andric } 253*81ad6265SDimitry Andric case ELFMovwAbsG2: { 254*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 255*81ad6265SDimitry Andric if (!aarch64::isMoveWideImm16(Instr) || 256*81ad6265SDimitry Andric aarch64::getMoveWide16Shift(Instr) != 32) 257*81ad6265SDimitry Andric return make_error<JITLinkError>( 258*81ad6265SDimitry Andric "R_AARCH64_MOVW_UABS_G2_NC target is not a " 259*81ad6265SDimitry Andric "MOVK/MOVZ (imm16, LSL #32) instruction"); 260*81ad6265SDimitry Andric 261*81ad6265SDimitry Andric Kind = aarch64::MoveWide16; 262*81ad6265SDimitry Andric break; 263*81ad6265SDimitry Andric } 264*81ad6265SDimitry Andric case ELFMovwAbsG3: { 265*81ad6265SDimitry Andric uint32_t Instr = *(const ulittle32_t *)FixupContent; 266*81ad6265SDimitry Andric if (!aarch64::isMoveWideImm16(Instr) || 267*81ad6265SDimitry Andric aarch64::getMoveWide16Shift(Instr) != 48) 268*81ad6265SDimitry Andric return make_error<JITLinkError>( 269*81ad6265SDimitry Andric "R_AARCH64_MOVW_UABS_G3 target is not a " 270*81ad6265SDimitry Andric "MOVK/MOVZ (imm16, LSL #48) instruction"); 271*81ad6265SDimitry Andric 272*81ad6265SDimitry Andric Kind = aarch64::MoveWide16; 273*81ad6265SDimitry Andric break; 274*81ad6265SDimitry Andric } 275*81ad6265SDimitry Andric case ELFAbs64: { 276*81ad6265SDimitry Andric Kind = aarch64::Pointer64; 277*81ad6265SDimitry Andric break; 278*81ad6265SDimitry Andric } 279*81ad6265SDimitry Andric case ELFPrel32: { 280*81ad6265SDimitry Andric Kind = aarch64::Delta32; 281*81ad6265SDimitry Andric break; 282*81ad6265SDimitry Andric } 283*81ad6265SDimitry Andric case ELFPrel64: { 284*81ad6265SDimitry Andric Kind = aarch64::Delta64; 285*81ad6265SDimitry Andric break; 286*81ad6265SDimitry Andric } 287*81ad6265SDimitry Andric case ELFAdrGOTPage21: { 288*81ad6265SDimitry Andric Kind = aarch64::GOTPage21; 289*81ad6265SDimitry Andric break; 290*81ad6265SDimitry Andric } 291*81ad6265SDimitry Andric case ELFLd64GOTLo12: { 292*81ad6265SDimitry Andric Kind = aarch64::GOTPageOffset12; 293*81ad6265SDimitry Andric break; 294*81ad6265SDimitry Andric } 295*81ad6265SDimitry Andric }; 296*81ad6265SDimitry Andric 297*81ad6265SDimitry Andric Edge GE(Kind, Offset, *GraphSymbol, Addend); 298349cc55cSDimitry Andric LLVM_DEBUG({ 299349cc55cSDimitry Andric dbgs() << " "; 300*81ad6265SDimitry Andric printEdge(dbgs(), BlockToFix, GE, aarch64::getEdgeKindName(Kind)); 301349cc55cSDimitry Andric dbgs() << "\n"; 302349cc55cSDimitry Andric }); 303349cc55cSDimitry Andric 30404eeddc0SDimitry Andric BlockToFix.addEdge(std::move(GE)); 305349cc55cSDimitry Andric return Error::success(); 306349cc55cSDimitry Andric } 307349cc55cSDimitry Andric 308*81ad6265SDimitry Andric /// Return the string name of the given ELF aarch64 edge kind. 309*81ad6265SDimitry Andric const char *getELFAArch64RelocationKindName(Edge::Kind R) { 310*81ad6265SDimitry Andric switch (R) { 311*81ad6265SDimitry Andric case ELFCall26: 312*81ad6265SDimitry Andric return "ELFCall26"; 313*81ad6265SDimitry Andric case ELFAdrPage21: 314*81ad6265SDimitry Andric return "ELFAdrPage21"; 315*81ad6265SDimitry Andric case ELFAddAbs12: 316*81ad6265SDimitry Andric return "ELFAddAbs12"; 317*81ad6265SDimitry Andric case ELFLdSt8Abs12: 318*81ad6265SDimitry Andric return "ELFLdSt8Abs12"; 319*81ad6265SDimitry Andric case ELFLdSt16Abs12: 320*81ad6265SDimitry Andric return "ELFLdSt16Abs12"; 321*81ad6265SDimitry Andric case ELFLdSt32Abs12: 322*81ad6265SDimitry Andric return "ELFLdSt32Abs12"; 323*81ad6265SDimitry Andric case ELFLdSt64Abs12: 324*81ad6265SDimitry Andric return "ELFLdSt64Abs12"; 325*81ad6265SDimitry Andric case ELFLdSt128Abs12: 326*81ad6265SDimitry Andric return "ELFLdSt128Abs12"; 327*81ad6265SDimitry Andric case ELFMovwAbsG0: 328*81ad6265SDimitry Andric return "ELFMovwAbsG0"; 329*81ad6265SDimitry Andric case ELFMovwAbsG1: 330*81ad6265SDimitry Andric return "ELFMovwAbsG1"; 331*81ad6265SDimitry Andric case ELFMovwAbsG2: 332*81ad6265SDimitry Andric return "ELFMovwAbsG2"; 333*81ad6265SDimitry Andric case ELFMovwAbsG3: 334*81ad6265SDimitry Andric return "ELFMovwAbsG3"; 335*81ad6265SDimitry Andric case ELFAbs64: 336*81ad6265SDimitry Andric return "ELFAbs64"; 337*81ad6265SDimitry Andric case ELFPrel32: 338*81ad6265SDimitry Andric return "ELFPrel32"; 339*81ad6265SDimitry Andric case ELFPrel64: 340*81ad6265SDimitry Andric return "ELFPrel64"; 341*81ad6265SDimitry Andric case ELFAdrGOTPage21: 342*81ad6265SDimitry Andric return "ELFAdrGOTPage21"; 343*81ad6265SDimitry Andric case ELFLd64GOTLo12: 344*81ad6265SDimitry Andric return "ELFLd64GOTLo12"; 345*81ad6265SDimitry Andric default: 346*81ad6265SDimitry Andric return getGenericEdgeKindName(static_cast<Edge::Kind>(R)); 347*81ad6265SDimitry Andric } 348*81ad6265SDimitry Andric } 349*81ad6265SDimitry Andric 350349cc55cSDimitry Andric public: 351349cc55cSDimitry Andric ELFLinkGraphBuilder_aarch64(StringRef FileName, 352349cc55cSDimitry Andric const object::ELFFile<ELFT> &Obj, const Triple T) 353349cc55cSDimitry Andric : ELFLinkGraphBuilder<ELFT>(Obj, std::move(T), FileName, 354349cc55cSDimitry Andric aarch64::getEdgeKindName) {} 355349cc55cSDimitry Andric }; 356349cc55cSDimitry Andric 357*81ad6265SDimitry Andric Error buildTables_ELF_aarch64(LinkGraph &G) { 358*81ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n"); 359*81ad6265SDimitry Andric 360*81ad6265SDimitry Andric aarch64::GOTTableManager GOT; 361*81ad6265SDimitry Andric aarch64::PLTTableManager PLT(GOT); 362*81ad6265SDimitry Andric visitExistingEdges(G, GOT, PLT); 363*81ad6265SDimitry Andric return Error::success(); 364*81ad6265SDimitry Andric } 365*81ad6265SDimitry Andric 366*81ad6265SDimitry Andric } // namespace 367*81ad6265SDimitry Andric 368*81ad6265SDimitry Andric namespace llvm { 369*81ad6265SDimitry Andric namespace jitlink { 370*81ad6265SDimitry Andric 371349cc55cSDimitry Andric Expected<std::unique_ptr<LinkGraph>> 372349cc55cSDimitry Andric createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) { 373349cc55cSDimitry Andric LLVM_DEBUG({ 374349cc55cSDimitry Andric dbgs() << "Building jitlink graph for new input " 375349cc55cSDimitry Andric << ObjectBuffer.getBufferIdentifier() << "...\n"; 376349cc55cSDimitry Andric }); 377349cc55cSDimitry Andric 378349cc55cSDimitry Andric auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer); 379349cc55cSDimitry Andric if (!ELFObj) 380349cc55cSDimitry Andric return ELFObj.takeError(); 381349cc55cSDimitry Andric 382349cc55cSDimitry Andric assert((*ELFObj)->getArch() == Triple::aarch64 && 383349cc55cSDimitry Andric "Only AArch64 (little endian) is supported for now"); 384349cc55cSDimitry Andric 385349cc55cSDimitry Andric auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj); 386349cc55cSDimitry Andric return ELFLinkGraphBuilder_aarch64<object::ELF64LE>((*ELFObj)->getFileName(), 387349cc55cSDimitry Andric ELFObjFile.getELFFile(), 388349cc55cSDimitry Andric (*ELFObj)->makeTriple()) 389349cc55cSDimitry Andric .buildGraph(); 390349cc55cSDimitry Andric } 391349cc55cSDimitry Andric 392349cc55cSDimitry Andric void link_ELF_aarch64(std::unique_ptr<LinkGraph> G, 393349cc55cSDimitry Andric std::unique_ptr<JITLinkContext> Ctx) { 394349cc55cSDimitry Andric PassConfiguration Config; 395349cc55cSDimitry Andric const Triple &TT = G->getTargetTriple(); 396349cc55cSDimitry Andric if (Ctx->shouldAddDefaultTargetPasses(TT)) { 397*81ad6265SDimitry Andric // Add eh-frame passses. 398*81ad6265SDimitry Andric Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame")); 399*81ad6265SDimitry Andric Config.PrePrunePasses.push_back(EHFrameEdgeFixer( 400*81ad6265SDimitry Andric ".eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64, 401*81ad6265SDimitry Andric aarch64::Delta32, aarch64::Delta64, aarch64::NegDelta32)); 402*81ad6265SDimitry Andric 403*81ad6265SDimitry Andric // Add a mark-live pass. 404349cc55cSDimitry Andric if (auto MarkLive = Ctx->getMarkLivePass(TT)) 405349cc55cSDimitry Andric Config.PrePrunePasses.push_back(std::move(MarkLive)); 406349cc55cSDimitry Andric else 407349cc55cSDimitry Andric Config.PrePrunePasses.push_back(markAllSymbolsLive); 408*81ad6265SDimitry Andric 409*81ad6265SDimitry Andric // Add an in-place GOT/Stubs build pass. 410*81ad6265SDimitry Andric Config.PostPrunePasses.push_back(buildTables_ELF_aarch64); 411349cc55cSDimitry Andric } 412*81ad6265SDimitry Andric 413349cc55cSDimitry Andric if (auto Err = Ctx->modifyPassConfig(*G, Config)) 414349cc55cSDimitry Andric return Ctx->notifyFailed(std::move(Err)); 415349cc55cSDimitry Andric 416349cc55cSDimitry Andric ELFJITLinker_aarch64::link(std::move(Ctx), std::move(G), std::move(Config)); 417349cc55cSDimitry Andric } 418349cc55cSDimitry Andric 419349cc55cSDimitry Andric } // namespace jitlink 420349cc55cSDimitry Andric } // namespace llvm 421