LLVM 20.0.0git
ELF_aarch64.cpp
Go to the documentation of this file.
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
18#include "llvm/Support/Endian.h"
19
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
32constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";
33
34class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
35 friend class JITLinker<ELFJITLinker_aarch64>;
36
37public:
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()))
44 [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); });
45 }
46
47private:
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 DefineExternalGOTSymbolIfPresent =
58 if (Sym.getName() == ELFGOTSymbolName)
59 if (auto *GOTSection = G.findSectionByName(
61 GOTSymbol = &Sym;
62 return {*GOTSection, true};
63 }
64 return {};
65 });
66
67 // Try to attach _GLOBAL_OFFSET_TABLE_ to the GOT if it's defined as an
68 // external.
69 if (auto Err = DefineExternalGOTSymbolIfPresent(G))
70 return Err;
71
72 // If we succeeded then we're done.
73 if (GOTSymbol)
74 return Error::success();
75
76 // Otherwise look for a GOT section: If it already has a start symbol we'll
77 // record it, otherwise we'll create our own.
78 // If there's a GOT section but we didn't find an external GOT symbol...
79 if (auto *GOTSection =
80 G.findSectionByName(aarch64::GOTTableManager::getSectionName())) {
81
82 // Check for an existing defined symbol.
83 for (auto *Sym : GOTSection->symbols())
84 if (Sym->getName() == ELFGOTSymbolName) {
85 GOTSymbol = Sym;
86 return Error::success();
87 }
88
89 // If there's no defined symbol then create one.
90 SectionRange SR(*GOTSection);
91 if (SR.empty())
92 GOTSymbol =
93 &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,
94 Linkage::Strong, Scope::Local, true);
95 else
96 GOTSymbol =
97 &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
98 Linkage::Strong, Scope::Local, false, true);
99 }
100
101 // If we still haven't found a GOT symbol then double check the externals.
102 // We may have a GOT-relative reference but no GOT section, in which case
103 // we just need to point the GOT symbol at some address in this graph.
104 if (!GOTSymbol) {
105 for (auto *Sym : G.external_symbols()) {
106 if (Sym->getName() == ELFGOTSymbolName) {
107 auto Blocks = G.blocks();
108 if (!Blocks.empty()) {
109 G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());
110 GOTSymbol = Sym;
111 break;
112 }
113 }
114 }
115 }
116
117 return Error::success();
118 }
119};
120
121template <typename ELFT>
122class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
123private:
124 enum ELFAArch64RelocationKind : Edge::Kind {
125 ELFCall26 = Edge::FirstRelocation,
126 ELFLdrLo19,
127 ELFAdrLo21,
128 ELFAdrPage21,
129 ELFAddAbs12,
130 ELFLdSt8Abs12,
131 ELFLdSt16Abs12,
132 ELFLdSt32Abs12,
133 ELFLdSt64Abs12,
134 ELFLdSt128Abs12,
135 ELFMovwAbsG0,
136 ELFMovwAbsG1,
137 ELFMovwAbsG2,
138 ELFMovwAbsG3,
139 ELFTstBr14,
140 ELFCondBr19,
141 ELFAbs32,
142 ELFAbs64,
143 ELFPrel32,
144 ELFPrel64,
145 ELFAdrGOTPage21,
146 ELFLd64GOTLo12,
147 ELFLd64GOTPAGELo15,
148 ELFTLSDescAdrPage21,
149 ELFTLSDescAddLo12,
150 ELFTLSDescLd64Lo12,
151 ELFTLSDescCall,
152 };
153
155 getRelocationKind(const uint32_t Type) {
156 using namespace aarch64;
157 switch (Type) {
158 case ELF::R_AARCH64_CALL26:
159 case ELF::R_AARCH64_JUMP26:
160 return ELFCall26;
161 case ELF::R_AARCH64_LD_PREL_LO19:
162 return ELFLdrLo19;
163 case ELF::R_AARCH64_ADR_PREL_LO21:
164 return ELFAdrLo21;
165 case ELF::R_AARCH64_ADR_PREL_PG_HI21:
166 return ELFAdrPage21;
167 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
168 return ELFAddAbs12;
169 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
170 return ELFLdSt8Abs12;
171 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
172 return ELFLdSt16Abs12;
173 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
174 return ELFLdSt32Abs12;
175 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
176 return ELFLdSt64Abs12;
177 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
178 return ELFLdSt128Abs12;
179 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
180 return ELFMovwAbsG0;
181 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
182 return ELFMovwAbsG1;
183 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
184 return ELFMovwAbsG2;
185 case ELF::R_AARCH64_MOVW_UABS_G3:
186 return ELFMovwAbsG3;
187 case ELF::R_AARCH64_TSTBR14:
188 return ELFTstBr14;
189 case ELF::R_AARCH64_CONDBR19:
190 return ELFCondBr19;
191 case ELF::R_AARCH64_ABS32:
192 return ELFAbs32;
193 case ELF::R_AARCH64_ABS64:
194 return ELFAbs64;
195 case ELF::R_AARCH64_PREL32:
196 return ELFPrel32;
197 case ELF::R_AARCH64_PREL64:
198 return ELFPrel64;
199 case ELF::R_AARCH64_ADR_GOT_PAGE:
200 return ELFAdrGOTPage21;
201 case ELF::R_AARCH64_LD64_GOT_LO12_NC:
202 return ELFLd64GOTLo12;
203 case ELF::R_AARCH64_LD64_GOTPAGE_LO15:
204 return ELFLd64GOTPAGELo15;
205 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
206 return ELFTLSDescAdrPage21;
207 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
208 return ELFTLSDescAddLo12;
209 case ELF::R_AARCH64_TLSDESC_LD64_LO12:
210 return ELFTLSDescLd64Lo12;
211 case ELF::R_AARCH64_TLSDESC_CALL:
212 return ELFTLSDescCall;
213 }
214
215 return make_error<JITLinkError>(
216 "Unsupported aarch64 relocation:" + formatv("{0:d}: ", Type) +
218 }
219
220 Error addRelocations() override {
221 LLVM_DEBUG(dbgs() << "Processing relocations:\n");
222
224 using Self = ELFLinkGraphBuilder_aarch64<ELFT>;
225 for (const auto &RelSect : Base::Sections)
226 if (Error Err = Base::forEachRelaRelocation(RelSect, this,
227 &Self::addSingleRelocation))
228 return Err;
229
230 return Error::success();
231 }
232
233 Error addSingleRelocation(const typename ELFT::Rela &Rel,
234 const typename ELFT::Shdr &FixupSect,
235 Block &BlockToFix) {
238
239 uint32_t SymbolIndex = Rel.getSymbol(false);
240 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
241 if (!ObjSymbol)
242 return ObjSymbol.takeError();
243
244 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
245 if (!GraphSymbol)
246 return make_error<StringError>(
247 formatv("Could not find symbol at given index, did you add it to "
248 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
249 SymbolIndex, (*ObjSymbol)->st_shndx,
250 Base::GraphSymbols.size()),
252
253 uint32_t Type = Rel.getType(false);
254 Expected<ELFAArch64RelocationKind> RelocKind = getRelocationKind(Type);
255 if (!RelocKind)
256 return RelocKind.takeError();
257
258 int64_t Addend = Rel.r_addend;
259 orc::ExecutorAddr FixupAddress =
260 orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
261 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
262
263 // Get a pointer to the fixup content.
264 const void *FixupContent = BlockToFix.getContent().data() +
265 (FixupAddress - BlockToFix.getAddress());
266
268
269 switch (*RelocKind) {
270 case ELFCall26: {
272 break;
273 }
274 case ELFLdrLo19: {
275 uint32_t Instr = *(const ulittle32_t *)FixupContent;
276 if (!aarch64::isLDRLiteral(Instr))
277 return make_error<JITLinkError>(
278 "R_AARCH64_LDR_PREL_LO19 target is not an LDR Literal instruction");
279
281 break;
282 }
283 case ELFAdrLo21: {
284 uint32_t Instr = *(const ulittle32_t *)FixupContent;
285 if (!aarch64::isADR(Instr))
286 return make_error<JITLinkError>(
287 "R_AARCH64_ADR_PREL_LO21 target is not an ADR instruction");
288
290 break;
291 }
292 case ELFAdrPage21: {
294 break;
295 }
296 case ELFAddAbs12: {
298 break;
299 }
300 case ELFLdSt8Abs12: {
301 uint32_t Instr = *(const ulittle32_t *)FixupContent;
302 if (!aarch64::isLoadStoreImm12(Instr) ||
304 return make_error<JITLinkError>(
305 "R_AARCH64_LDST8_ABS_LO12_NC target is not a "
306 "LDRB/STRB (imm12) instruction");
307
309 break;
310 }
311 case ELFLdSt16Abs12: {
312 uint32_t Instr = *(const ulittle32_t *)FixupContent;
313 if (!aarch64::isLoadStoreImm12(Instr) ||
315 return make_error<JITLinkError>(
316 "R_AARCH64_LDST16_ABS_LO12_NC target is not a "
317 "LDRH/STRH (imm12) instruction");
318
320 break;
321 }
322 case ELFLdSt32Abs12: {
323 uint32_t Instr = *(const ulittle32_t *)FixupContent;
324 if (!aarch64::isLoadStoreImm12(Instr) ||
326 return make_error<JITLinkError>(
327 "R_AARCH64_LDST32_ABS_LO12_NC target is not a "
328 "LDR/STR (imm12, 32 bit) instruction");
329
331 break;
332 }
333 case ELFLdSt64Abs12: {
334 uint32_t Instr = *(const ulittle32_t *)FixupContent;
335 if (!aarch64::isLoadStoreImm12(Instr) ||
337 return make_error<JITLinkError>(
338 "R_AARCH64_LDST64_ABS_LO12_NC target is not a "
339 "LDR/STR (imm12, 64 bit) instruction");
340
342 break;
343 }
344 case ELFLdSt128Abs12: {
345 uint32_t Instr = *(const ulittle32_t *)FixupContent;
346 if (!aarch64::isLoadStoreImm12(Instr) ||
348 return make_error<JITLinkError>(
349 "R_AARCH64_LDST128_ABS_LO12_NC target is not a "
350 "LDR/STR (imm12, 128 bit) instruction");
351
353 break;
354 }
355 case ELFMovwAbsG0: {
356 uint32_t Instr = *(const ulittle32_t *)FixupContent;
357 if (!aarch64::isMoveWideImm16(Instr) ||
358 aarch64::getMoveWide16Shift(Instr) != 0)
359 return make_error<JITLinkError>(
360 "R_AARCH64_MOVW_UABS_G0_NC target is not a "
361 "MOVK/MOVZ (imm16, LSL #0) instruction");
362
364 break;
365 }
366 case ELFMovwAbsG1: {
367 uint32_t Instr = *(const ulittle32_t *)FixupContent;
368 if (!aarch64::isMoveWideImm16(Instr) ||
369 aarch64::getMoveWide16Shift(Instr) != 16)
370 return make_error<JITLinkError>(
371 "R_AARCH64_MOVW_UABS_G1_NC target is not a "
372 "MOVK/MOVZ (imm16, LSL #16) instruction");
373
375 break;
376 }
377 case ELFMovwAbsG2: {
378 uint32_t Instr = *(const ulittle32_t *)FixupContent;
379 if (!aarch64::isMoveWideImm16(Instr) ||
380 aarch64::getMoveWide16Shift(Instr) != 32)
381 return make_error<JITLinkError>(
382 "R_AARCH64_MOVW_UABS_G2_NC target is not a "
383 "MOVK/MOVZ (imm16, LSL #32) instruction");
384
386 break;
387 }
388 case ELFMovwAbsG3: {
389 uint32_t Instr = *(const ulittle32_t *)FixupContent;
390 if (!aarch64::isMoveWideImm16(Instr) ||
391 aarch64::getMoveWide16Shift(Instr) != 48)
392 return make_error<JITLinkError>(
393 "R_AARCH64_MOVW_UABS_G3 target is not a "
394 "MOVK/MOVZ (imm16, LSL #48) instruction");
395
397 break;
398 }
399 case ELFTstBr14: {
400 uint32_t Instr = *(const ulittle32_t *)FixupContent;
402 return make_error<JITLinkError>("R_AARCH64_TSTBR14 target is not a "
403 "test and branch instruction");
404
406 break;
407 }
408 case ELFCondBr19: {
409 uint32_t Instr = *(const ulittle32_t *)FixupContent;
410 if (!aarch64::isCondBranchImm19(Instr) &&
412 return make_error<JITLinkError>("R_AARCH64_CONDBR19 target is not a "
413 "conditional branch instruction");
414
416 break;
417 }
418 case ELFAbs32: {
420 break;
421 }
422 case ELFAbs64: {
424 break;
425 }
426 case ELFPrel32: {
428 break;
429 }
430 case ELFPrel64: {
432 break;
433 }
434 case ELFAdrGOTPage21: {
436 break;
437 }
438 case ELFLd64GOTLo12: {
440 break;
441 }
442 case ELFLd64GOTPAGELo15: {
444 break;
445 }
446 case ELFTLSDescAdrPage21: {
448 break;
449 }
450 case ELFTLSDescAddLo12:
451 case ELFTLSDescLd64Lo12: {
453 break;
454 }
455 case ELFTLSDescCall: {
456 return Error::success();
457 }
458 };
459
460 Edge GE(Kind, Offset, *GraphSymbol, Addend);
461 LLVM_DEBUG({
462 dbgs() << " ";
463 printEdge(dbgs(), BlockToFix, GE, aarch64::getEdgeKindName(Kind));
464 dbgs() << "\n";
465 });
466
467 BlockToFix.addEdge(std::move(GE));
468
469 return Error::success();
470 }
471
472 /// Return the string name of the given ELF aarch64 edge kind.
473 const char *getELFAArch64RelocationKindName(Edge::Kind R) {
474 switch (R) {
475 case ELFCall26:
476 return "ELFCall26";
477 case ELFAdrPage21:
478 return "ELFAdrPage21";
479 case ELFAddAbs12:
480 return "ELFAddAbs12";
481 case ELFLdSt8Abs12:
482 return "ELFLdSt8Abs12";
483 case ELFLdSt16Abs12:
484 return "ELFLdSt16Abs12";
485 case ELFLdSt32Abs12:
486 return "ELFLdSt32Abs12";
487 case ELFLdSt64Abs12:
488 return "ELFLdSt64Abs12";
489 case ELFLdSt128Abs12:
490 return "ELFLdSt128Abs12";
491 case ELFMovwAbsG0:
492 return "ELFMovwAbsG0";
493 case ELFMovwAbsG1:
494 return "ELFMovwAbsG1";
495 case ELFMovwAbsG2:
496 return "ELFMovwAbsG2";
497 case ELFMovwAbsG3:
498 return "ELFMovwAbsG3";
499 case ELFAbs32:
500 return "ELFAbs32";
501 case ELFAbs64:
502 return "ELFAbs64";
503 case ELFPrel32:
504 return "ELFPrel32";
505 case ELFPrel64:
506 return "ELFPrel64";
507 case ELFAdrGOTPage21:
508 return "ELFAdrGOTPage21";
509 case ELFLd64GOTLo12:
510 return "ELFLd64GOTLo12";
511 case ELFLd64GOTPAGELo15:
512 return "ELFLd64GOTPAGELo15";
513 case ELFTLSDescAdrPage21:
514 return "ELFTLSDescAdrPage21";
515 case ELFTLSDescAddLo12:
516 return "ELFTLSDescAddLo12";
517 case ELFTLSDescLd64Lo12:
518 return "ELFTLSDescLd64Lo12";
519 case ELFTLSDescCall:
520 return "ELFTLSDescCall";
521 default:
522 return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
523 }
524 }
525
526public:
527 ELFLinkGraphBuilder_aarch64(StringRef FileName,
528 const object::ELFFile<ELFT> &Obj, Triple TT,
529 SubtargetFeatures Features)
530 : ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
531 FileName, aarch64::getEdgeKindName) {}
532};
533
534// TLS Info Builder.
535class TLSInfoTableManager_ELF_aarch64
536 : public TableManager<TLSInfoTableManager_ELF_aarch64> {
537public:
538 static StringRef getSectionName() { return "$__TLSINFO"; }
539
540 static const uint8_t TLSInfoEntryContent[16];
541
542 bool visitEdge(LinkGraph &G, Block *B, Edge &E) { return false; }
543
544 Symbol &createEntry(LinkGraph &G, Symbol &Target) {
545 // the TLS Info entry's key value will be written by the fixTLVSectionByName
546 // pass, so create mutable content.
547 auto &TLSInfoEntry = G.createMutableContentBlock(
548 getTLSInfoSection(G), G.allocateContent(getTLSInfoEntryContent()),
549 orc::ExecutorAddr(), 8, 0);
550 TLSInfoEntry.addEdge(aarch64::Pointer64, 8, Target, 0);
551 return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false);
552 }
553
554private:
555 Section &getTLSInfoSection(LinkGraph &G) {
556 if (!TLSInfoTable)
557 TLSInfoTable = &G.createSection(getSectionName(), orc::MemProt::Read);
558 return *TLSInfoTable;
559 }
560
561 ArrayRef<char> getTLSInfoEntryContent() const {
562 return {reinterpret_cast<const char *>(TLSInfoEntryContent),
563 sizeof(TLSInfoEntryContent)};
564 }
565
566 Section *TLSInfoTable = nullptr;
567};
568
569const uint8_t TLSInfoTableManager_ELF_aarch64::TLSInfoEntryContent[16] = {
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*data address*/
572};
573
574// TLS Descriptor Builder.
575class TLSDescTableManager_ELF_aarch64
576 : public TableManager<TLSDescTableManager_ELF_aarch64> {
577public:
578 TLSDescTableManager_ELF_aarch64(
579 TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager)
580 : TLSInfoTableManager(TLSInfoTableManager) {}
581
582 static StringRef getSectionName() { return "$__TLSDESC"; }
583
584 static const uint8_t TLSDescEntryContent[16];
585
586 bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
587 Edge::Kind KindToSet = Edge::Invalid;
588 switch (E.getKind()) {
590 KindToSet = aarch64::Page21;
591 break;
592 }
594 KindToSet = aarch64::PageOffset12;
595 break;
596 }
597 default:
598 return false;
599 }
600 assert(KindToSet != Edge::Invalid &&
601 "Fell through switch, but no new kind to set");
602 DEBUG_WITH_TYPE("jitlink", {
603 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
604 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
605 << formatv("{0:x}", E.getOffset()) << ")\n";
606 });
607 E.setKind(KindToSet);
609 return true;
610 }
611
612 Symbol &createEntry(LinkGraph &G, Symbol &Target) {
613 auto &EntryBlock =
614 G.createContentBlock(getTLSDescSection(G), getTLSDescBlockContent(),
615 orc::ExecutorAddr(), 8, 0);
616 EntryBlock.addEdge(aarch64::Pointer64, 0, getTLSDescResolver(G), 0);
617 EntryBlock.addEdge(aarch64::Pointer64, 8,
618 TLSInfoTableManager.getEntryForTarget(G, Target), 0);
619 return G.addAnonymousSymbol(EntryBlock, 0, 8, false, false);
620 }
621
622private:
623 Section &getTLSDescSection(LinkGraph &G) {
624 if (!GOTSection)
625 GOTSection = &G.createSection(getSectionName(), orc::MemProt::Read);
626 return *GOTSection;
627 }
628
629 Symbol &getTLSDescResolver(LinkGraph &G) {
630 if (!TLSDescResolver)
631 TLSDescResolver = &G.addExternalSymbol("__tlsdesc_resolver", 8, false);
632 return *TLSDescResolver;
633 }
634
635 ArrayRef<char> getTLSDescBlockContent() {
636 return {reinterpret_cast<const char *>(TLSDescEntryContent),
637 sizeof(TLSDescEntryContent)};
638 }
639
640 Section *GOTSection = nullptr;
641 Symbol *TLSDescResolver = nullptr;
642 TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager;
643};
644
645const uint8_t TLSDescTableManager_ELF_aarch64::TLSDescEntryContent[16] = {
646 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, /*resolver function pointer*/
648 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00 /*pointer to tls info*/
650};
651
652Error buildTables_ELF_aarch64(LinkGraph &G) {
653 LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
654
657 TLSInfoTableManager_ELF_aarch64 TLSInfo;
658 TLSDescTableManager_ELF_aarch64 TLSDesc(TLSInfo);
659 visitExistingEdges(G, GOT, PLT, TLSDesc, TLSInfo);
660 return Error::success();
661}
662
663} // namespace
664
665namespace llvm {
666namespace jitlink {
667
670 LLVM_DEBUG({
671 dbgs() << "Building jitlink graph for new input "
672 << ObjectBuffer.getBufferIdentifier() << "...\n";
673 });
674
675 auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer);
676 if (!ELFObj)
677 return ELFObj.takeError();
678
679 auto Features = (*ELFObj)->getFeatures();
680 if (!Features)
681 return Features.takeError();
682
683 assert((*ELFObj)->getArch() == Triple::aarch64 &&
684 "Only AArch64 (little endian) is supported for now");
685
686 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
687 return ELFLinkGraphBuilder_aarch64<object::ELF64LE>(
688 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
689 (*ELFObj)->makeTriple(), std::move(*Features))
690 .buildGraph();
691}
692
693void link_ELF_aarch64(std::unique_ptr<LinkGraph> G,
694 std::unique_ptr<JITLinkContext> Ctx) {
696 const Triple &TT = G->getTargetTriple();
697 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
698 // Add eh-frame passes.
699 Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame"));
700 Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
701 ".eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64,
703 Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame"));
704
705 // Add a mark-live pass.
706 if (auto MarkLive = Ctx->getMarkLivePass(TT))
707 Config.PrePrunePasses.push_back(std::move(MarkLive));
708 else
709 Config.PrePrunePasses.push_back(markAllSymbolsLive);
710
711 // Resolve any external section start / end symbols.
712 Config.PostAllocationPasses.push_back(
715
716 // Add an in-place GOT/TLS/Stubs build pass.
717 Config.PostPrunePasses.push_back(buildTables_ELF_aarch64);
718 }
719
720 if (auto Err = Ctx->modifyPassConfig(*G, Config))
721 return Ctx->notifyFailed(std::move(Err));
722
723 ELFJITLinker_aarch64::link(std::move(Ctx), std::move(G), std::move(Config));
724}
725
726} // namespace jitlink
727} // namespace llvm
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:64
RelaxConfig Config
Definition: ELF_riscv.cpp:506
DenseMap< Block *, BlockRelaxAux > Blocks
Definition: ELF_riscv.cpp:507
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define G(x, y, z)
Definition: MD5.cpp:56
if(PassOpts->AAPipeline)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T * data() const
Definition: ArrayRef.h:162
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
StringRef getBufferIdentifier() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Manages the enabling and disabling of subtarget specific features.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
Represents an address in the executor process.
@ EM_AARCH64
Definition: ELF.h:281
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:23
NodeAddr< InstrNode * > Instr
Definition: RDFGraph.h:389
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
Definition: Endian.h:285
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:98
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1856
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858