xref: /llvm-project/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp (revision 42595bdaefb6b066896c20b69ab66ff2a7fe8477)
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-exception
6 //
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 
27 using namespace llvm;
28 using namespace llvm::jitlink;
29 
30 namespace {
31 
32 constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";
33 
34 class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
35   friend class JITLinker<ELFJITLinker_aarch64>;
36 
37 public:
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 
47 private:
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 an
71     // 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'll
80     // 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 once
97             &G.addAbsoluteSymbol(InteredGOTSymbolName, orc::ExecutorAddr(), 0,
98                                  Linkage::Strong, Scope::Local, true);
99       else
100         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 case
107     // 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 
125 template <typename ELFT>
126 class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
127 private:
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(static_cast<Edge::Kind>(R));
527     }
528   }
529 
530 public:
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.
542 class TLSInfoTableManager_ELF_aarch64
543     : public TableManager<TLSInfoTableManager_ELF_aarch64> {
544 public:
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 fixTLVSectionByName
553     // 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 
561 private:
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 
576 const 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.
582 class TLSDescTableManager_ELF_aarch64
583     : public TableManager<TLSDescTableManager_ELF_aarch64> {
584 public:
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 
629 private:
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 
652 const 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 
659 Error 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 } // namespace
671 
672 namespace llvm {
673 namespace jitlink {
674 
675 Expected<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 
700 void 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     else
716       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 jitlink
734 } // namespace llvm
735