Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
35271 views
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:
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:
42
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>
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
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
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.
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:
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:
455
static StringRef getSectionName() { return "$__TLSINFO"; }
456
457
static const uint8_t TLSInfoEntryContent[16];
458
459
bool visitEdge(LinkGraph &G, Block *B, Edge &E) { return false; }
460
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:
472
Section &getTLSInfoSection(LinkGraph &G) {
473
if (!TLSInfoTable)
474
TLSInfoTable = &G.createSection(getSectionName(), orc::MemProt::Read);
475
return *TLSInfoTable;
476
}
477
478
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:
495
TLSDescTableManager_ELF_aarch64(
496
TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager)
497
: TLSInfoTableManager(TLSInfoTableManager) {}
498
499
static StringRef getSectionName() { return "$__TLSDESC"; }
500
501
static const uint8_t TLSDescEntryContent[16];
502
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
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:
540
Section &getTLSDescSection(LinkGraph &G) {
541
if (!GOTSection)
542
GOTSection = &G.createSection(getSectionName(), orc::MemProt::Read);
543
return *GOTSection;
544
}
545
546
Symbol &getTLSDescResolver(LinkGraph &G) {
547
if (!TLSDescResolver)
548
TLSDescResolver = &G.addExternalSymbol("__tlsdesc_resolver", 8, false);
549
return *TLSDescResolver;
550
}
551
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
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>>
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
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
646