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