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