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