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

source code of llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp