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