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