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
27using namespace llvm;
28using namespace llvm::jitlink;
29
30namespace {
31
32class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
33 friend class JITLinker<ELFJITLinker_aarch64>;
34
35public:
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
41private:
42 Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
43 return aarch64::applyFixup(G, B, E);
44 }
45};
46
47template <typename ELFT>
48class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
49private:
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>
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 Args: "Unsupported aarch64 relocation:" + formatv(Fmt: "{0:d}: ", Vals: Type) +
140 object::getELFRelocationTypeName(Machine: ELF::EM_AARCH64, Type));
141 }
142
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
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 Args: "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 Args: "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 Args: "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 Args: "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 Args: "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 Args: "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 Args: "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 Args: "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 Args: "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 Args: "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 Args: "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>(Args: "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>(Args: "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(E: std::move(GE));
387
388 return Error::success();
389 }
390
391 /// Return the string name of the given ELF aarch64 edge kind.
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(K: static_cast<Edge::Kind>(R));
440 }
441 }
442
443public:
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.
452class TLSInfoTableManager_ELF_aarch64
453 : public TableManager<TLSInfoTableManager_ELF_aarch64> {
454public:
455 static StringRef getSectionName() { return "$__TLSINFO"; }
456
457 static const uint8_t TLSInfoEntryContent[16];
458
459 bool visitEdge(LinkGraph &G, Block *B, Edge &E) { return false; }
460
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 Parent&: getTLSInfoSection(G), MutableContent: G.allocateContent(Source: getTLSInfoEntryContent()),
466 Address: orc::ExecutorAddr(), Alignment: 8, AlignmentOffset: 0);
467 TLSInfoEntry.addEdge(K: aarch64::Pointer64, Offset: 8, Target, Addend: 0);
468 return G.addAnonymousSymbol(Content&: TLSInfoEntry, Offset: 0, Size: 16, IsCallable: false, IsLive: false);
469 }
470
471private:
472 Section &getTLSInfoSection(LinkGraph &G) {
473 if (!TLSInfoTable)
474 TLSInfoTable = &G.createSection(Name: getSectionName(), Prot: orc::MemProt::Read);
475 return *TLSInfoTable;
476 }
477
478 ArrayRef<char> getTLSInfoEntryContent() const {
479 return {reinterpret_cast<const char *>(TLSInfoEntryContent),
480 sizeof(TLSInfoEntryContent)};
481 }
482
483 Section *TLSInfoTable = nullptr;
484};
485
486const 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.
492class TLSDescTableManager_ELF_aarch64
493 : public TableManager<TLSDescTableManager_ELF_aarch64> {
494public:
495 TLSDescTableManager_ELF_aarch64(
496 TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager)
497 : TLSInfoTableManager(TLSInfoTableManager) {}
498
499 static StringRef getSectionName() { return "$__TLSDESC"; }
500
501 static const uint8_t TLSDescEntryContent[16];
502
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, Target&: E.getTarget()));
526 return true;
527 }
528
529 Symbol &createEntry(LinkGraph &G, Symbol &Target) {
530 auto &EntryBlock =
531 G.createContentBlock(Parent&: getTLSDescSection(G), Content: getTLSDescBlockContent(),
532 Address: orc::ExecutorAddr(), Alignment: 8, AlignmentOffset: 0);
533 EntryBlock.addEdge(K: aarch64::Pointer64, Offset: 0, Target&: getTLSDescResolver(G), Addend: 0);
534 EntryBlock.addEdge(K: aarch64::Pointer64, Offset: 8,
535 Target&: TLSInfoTableManager.getEntryForTarget(G, Target), Addend: 0);
536 return G.addAnonymousSymbol(Content&: EntryBlock, Offset: 0, Size: 8, IsCallable: false, IsLive: false);
537 }
538
539private:
540 Section &getTLSDescSection(LinkGraph &G) {
541 if (!GOTSection)
542 GOTSection = &G.createSection(Name: getSectionName(), Prot: orc::MemProt::Read);
543 return *GOTSection;
544 }
545
546 Symbol &getTLSDescResolver(LinkGraph &G) {
547 if (!TLSDescResolver)
548 TLSDescResolver = &G.addExternalSymbol(Name: "__tlsdesc_resolver", Size: 8, IsWeaklyReferenced: false);
549 return *TLSDescResolver;
550 }
551
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
562const 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
569Error 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, Vs&: GOT, Vs&: PLT, Vs&: TLSDesc, Vs&: TLSInfo);
577 return Error::success();
578}
579
580} // namespace
581
582namespace llvm {
583namespace jitlink {
584
585Expected<std::unique_ptr<LinkGraph>>
586createLinkGraphFromELFObject_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(Object: 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>>(Val&: **ELFObj);
604 return ELFLinkGraphBuilder_aarch64<object::ELF64LE>(
605 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
606 (*ELFObj)->makeTriple(), std::move(*Features))
607 .buildGraph();
608}
609
610void 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(x: DWARFRecordSectionSplitter(".eh_frame"));
617 Config.PrePrunePasses.push_back(x: EHFrameEdgeFixer(
618 ".eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64,
619 aarch64::Delta32, aarch64::Delta64, aarch64::NegDelta32));
620 Config.PrePrunePasses.push_back(x: EHFrameNullTerminator(".eh_frame"));
621
622 // Add a mark-live pass.
623 if (auto MarkLive = Ctx->getMarkLivePass(TT))
624 Config.PrePrunePasses.push_back(x: std::move(MarkLive));
625 else
626 Config.PrePrunePasses.push_back(x: markAllSymbolsLive);
627
628 // Resolve any external section start / end symbols.
629 Config.PostAllocationPasses.push_back(
630 x: createDefineExternalSectionStartAndEndSymbolsPass(
631 F&: identifyELFSectionStartAndEndSymbols));
632
633 // Add an in-place GOT/TLS/Stubs build pass.
634 Config.PostPrunePasses.push_back(x: buildTables_ELF_aarch64);
635 }
636
637 if (auto Err = Ctx->modifyPassConfig(G&: *G, Config))
638 return Ctx->notifyFailed(Err: std::move(Err));
639
640 ELFJITLinker_aarch64::link(Args: std::move(Ctx), Args: std::move(G), Args: std::move(Config));
641}
642
643} // namespace jitlink
644} // namespace llvm
645