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/ELFLinkGraphBuilder.h
35271 views
1
//===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
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
// Generic ELF LinkGraph building code.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14
#define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
15
16
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
17
#include "llvm/Object/ELF.h"
18
#include "llvm/Support/Debug.h"
19
#include "llvm/Support/Error.h"
20
#include "llvm/Support/FormatVariadic.h"
21
22
#define DEBUG_TYPE "jitlink"
23
24
namespace llvm {
25
namespace jitlink {
26
27
/// Common link-graph building code shared between all ELFFiles.
28
class ELFLinkGraphBuilderBase {
29
public:
30
ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
31
virtual ~ELFLinkGraphBuilderBase();
32
33
protected:
34
static bool isDwarfSection(StringRef SectionName) {
35
return llvm::is_contained(DwarfSectionNames, SectionName);
36
}
37
38
Section &getCommonSection() {
39
if (!CommonSection)
40
CommonSection = &G->createSection(
41
CommonSectionName, orc::MemProt::Read | orc::MemProt::Write);
42
return *CommonSection;
43
}
44
45
std::unique_ptr<LinkGraph> G;
46
47
private:
48
static StringRef CommonSectionName;
49
static ArrayRef<const char *> DwarfSectionNames;
50
51
Section *CommonSection = nullptr;
52
};
53
54
/// LinkGraph building code that's specific to the given ELFT, but common
55
/// across all architectures.
56
template <typename ELFT>
57
class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
58
using ELFFile = object::ELFFile<ELFT>;
59
60
public:
61
ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT,
62
SubtargetFeatures Features, StringRef FileName,
63
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
64
65
/// Debug sections are included in the graph by default. Use
66
/// setProcessDebugSections(false) to ignore them if debug info is not
67
/// needed.
68
ELFLinkGraphBuilder &setProcessDebugSections(bool ProcessDebugSections) {
69
this->ProcessDebugSections = ProcessDebugSections;
70
return *this;
71
}
72
73
/// Attempt to construct and return the LinkGraph.
74
Expected<std::unique_ptr<LinkGraph>> buildGraph();
75
76
/// Call to derived class to handle relocations. These require
77
/// architecture specific knowledge to map to JITLink edge kinds.
78
virtual Error addRelocations() = 0;
79
80
protected:
81
using ELFSectionIndex = unsigned;
82
using ELFSymbolIndex = unsigned;
83
84
bool isRelocatable() const {
85
return Obj.getHeader().e_type == llvm::ELF::ET_REL;
86
}
87
88
void setGraphBlock(ELFSectionIndex SecIndex, Block *B) {
89
assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
90
GraphBlocks[SecIndex] = B;
91
}
92
93
Block *getGraphBlock(ELFSectionIndex SecIndex) {
94
return GraphBlocks.lookup(SecIndex);
95
}
96
97
void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) {
98
assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
99
GraphSymbols[SymIndex] = &Sym;
100
}
101
102
Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) {
103
return GraphSymbols.lookup(SymIndex);
104
}
105
106
Expected<std::pair<Linkage, Scope>>
107
getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
108
109
/// Set the target flags on the given Symbol.
110
virtual TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) {
111
return TargetFlagsType{};
112
}
113
114
/// Get the physical offset of the symbol on the target platform.
115
virtual orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym,
116
TargetFlagsType Flags) {
117
return Sym.getValue();
118
}
119
120
Error prepare();
121
Error graphifySections();
122
Error graphifySymbols();
123
124
/// Override in derived classes to suppress certain sections in the link
125
/// graph.
126
virtual bool excludeSection(const typename ELFT::Shdr &Sect) const {
127
return false;
128
}
129
130
/// Traverse all matching ELFT::Rela relocation records in the given section.
131
/// The handler function Func should be callable with this signature:
132
/// Error(const typename ELFT::Rela &,
133
/// const typename ELFT::Shdr &, Section &)
134
///
135
template <typename RelocHandlerMethod>
136
Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
137
RelocHandlerMethod &&Func);
138
139
/// Traverse all matching ELFT::Rel relocation records in the given section.
140
/// The handler function Func should be callable with this signature:
141
/// Error(const typename ELFT::Rel &,
142
/// const typename ELFT::Shdr &, Section &)
143
///
144
template <typename RelocHandlerMethod>
145
Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
146
RelocHandlerMethod &&Func);
147
148
/// Traverse all matching rela relocation records in the given section.
149
/// Convenience wrapper to allow passing a member function for the handler.
150
///
151
template <typename ClassT, typename RelocHandlerMethod>
152
Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
153
ClassT *Instance, RelocHandlerMethod &&Method) {
154
return forEachRelaRelocation(
155
RelSect,
156
[Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
157
return (Instance->*Method)(Rel, Target, GS);
158
});
159
}
160
161
/// Traverse all matching rel relocation records in the given section.
162
/// Convenience wrapper to allow passing a member function for the handler.
163
///
164
template <typename ClassT, typename RelocHandlerMethod>
165
Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
166
ClassT *Instance, RelocHandlerMethod &&Method) {
167
return forEachRelRelocation(
168
RelSect,
169
[Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
170
return (Instance->*Method)(Rel, Target, GS);
171
});
172
}
173
174
const ELFFile &Obj;
175
176
typename ELFFile::Elf_Shdr_Range Sections;
177
const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
178
StringRef SectionStringTab;
179
bool ProcessDebugSections = true;
180
181
// Maps ELF section indexes to LinkGraph Blocks.
182
// Only SHF_ALLOC sections will have graph blocks.
183
DenseMap<ELFSectionIndex, Block *> GraphBlocks;
184
DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols;
185
DenseMap<const typename ELFFile::Elf_Shdr *,
186
ArrayRef<typename ELFFile::Elf_Word>>
187
ShndxTables;
188
};
189
190
template <typename ELFT>
191
ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
192
const ELFFile &Obj, Triple TT, SubtargetFeatures Features,
193
StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
194
: ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
195
FileName.str(), Triple(std::move(TT)), std::move(Features),
196
ELFT::Is64Bits ? 8 : 4, llvm::endianness(ELFT::Endianness),
197
std::move(GetEdgeKindName))),
198
Obj(Obj) {
199
LLVM_DEBUG(
200
{ dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
201
}
202
203
template <typename ELFT>
204
Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() {
205
if (!isRelocatable())
206
return make_error<JITLinkError>("Object is not a relocatable ELF file");
207
208
if (auto Err = prepare())
209
return std::move(Err);
210
211
if (auto Err = graphifySections())
212
return std::move(Err);
213
214
if (auto Err = graphifySymbols())
215
return std::move(Err);
216
217
if (auto Err = addRelocations())
218
return std::move(Err);
219
220
return std::move(G);
221
}
222
223
template <typename ELFT>
224
Expected<std::pair<Linkage, Scope>>
225
ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope(
226
const typename ELFT::Sym &Sym, StringRef Name) {
227
Linkage L = Linkage::Strong;
228
Scope S = Scope::Default;
229
230
switch (Sym.getBinding()) {
231
case ELF::STB_LOCAL:
232
S = Scope::Local;
233
break;
234
case ELF::STB_GLOBAL:
235
// Nothing to do here.
236
break;
237
case ELF::STB_WEAK:
238
case ELF::STB_GNU_UNIQUE:
239
L = Linkage::Weak;
240
break;
241
default:
242
return make_error<StringError>(
243
"Unrecognized symbol binding " +
244
Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
245
inconvertibleErrorCode());
246
}
247
248
switch (Sym.getVisibility()) {
249
case ELF::STV_DEFAULT:
250
case ELF::STV_PROTECTED:
251
// FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
252
// Orc support.
253
// Otherwise nothing to do here.
254
break;
255
case ELF::STV_HIDDEN:
256
// Default scope -> Hidden scope. No effect on local scope.
257
if (S == Scope::Default)
258
S = Scope::Hidden;
259
break;
260
case ELF::STV_INTERNAL:
261
return make_error<StringError>(
262
"Unrecognized symbol visibility " +
263
Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
264
inconvertibleErrorCode());
265
}
266
267
return std::make_pair(L, S);
268
}
269
270
template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
271
LLVM_DEBUG(dbgs() << " Preparing to build...\n");
272
273
// Get the sections array.
274
if (auto SectionsOrErr = Obj.sections())
275
Sections = *SectionsOrErr;
276
else
277
return SectionsOrErr.takeError();
278
279
// Get the section string table.
280
if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
281
SectionStringTab = *SectionStringTabOrErr;
282
else
283
return SectionStringTabOrErr.takeError();
284
285
// Get the SHT_SYMTAB section.
286
for (auto &Sec : Sections) {
287
if (Sec.sh_type == ELF::SHT_SYMTAB) {
288
if (!SymTabSec)
289
SymTabSec = &Sec;
290
else
291
return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
292
G->getName());
293
}
294
295
// Extended table.
296
if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
297
uint32_t SymtabNdx = Sec.sh_link;
298
if (SymtabNdx >= Sections.size())
299
return make_error<JITLinkError>("sh_link is out of bound");
300
301
auto ShndxTable = Obj.getSHNDXTable(Sec);
302
if (!ShndxTable)
303
return ShndxTable.takeError();
304
305
ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
306
}
307
}
308
309
return Error::success();
310
}
311
312
template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
313
LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
314
315
// For each section...
316
for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
317
318
auto &Sec = Sections[SecIndex];
319
320
// Start by getting the section name.
321
auto Name = Obj.getSectionName(Sec, SectionStringTab);
322
if (!Name)
323
return Name.takeError();
324
if (excludeSection(Sec)) {
325
LLVM_DEBUG({
326
dbgs() << " " << SecIndex << ": Skipping section \"" << *Name
327
<< "\" explicitly\n";
328
});
329
continue;
330
}
331
332
// Skip null sections.
333
if (Sec.sh_type == ELF::SHT_NULL) {
334
LLVM_DEBUG({
335
dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n";
336
});
337
continue;
338
}
339
340
// If the name indicates that it's a debug section then skip it: We don't
341
// support those yet.
342
if (!ProcessDebugSections && isDwarfSection(*Name)) {
343
LLVM_DEBUG({
344
dbgs() << " " << SecIndex << ": \"" << *Name
345
<< "\" is a debug section: "
346
"No graph section will be created.\n";
347
});
348
continue;
349
}
350
351
LLVM_DEBUG({
352
dbgs() << " " << SecIndex << ": Creating section for \"" << *Name
353
<< "\"\n";
354
});
355
356
// Get the section's memory protection flags.
357
orc::MemProt Prot = orc::MemProt::Read;
358
if (Sec.sh_flags & ELF::SHF_EXECINSTR)
359
Prot |= orc::MemProt::Exec;
360
if (Sec.sh_flags & ELF::SHF_WRITE)
361
Prot |= orc::MemProt::Write;
362
363
// Look for existing sections first.
364
auto *GraphSec = G->findSectionByName(*Name);
365
if (!GraphSec) {
366
GraphSec = &G->createSection(*Name, Prot);
367
// Non-SHF_ALLOC sections get NoAlloc memory lifetimes.
368
if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
369
GraphSec->setMemLifetime(orc::MemLifetime::NoAlloc);
370
LLVM_DEBUG({
371
dbgs() << " " << SecIndex << ": \"" << *Name
372
<< "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";
373
});
374
}
375
}
376
377
if (GraphSec->getMemProt() != Prot) {
378
std::string ErrMsg;
379
raw_string_ostream(ErrMsg)
380
<< "In " << G->getName() << ", section " << *Name
381
<< " is present more than once with different permissions: "
382
<< GraphSec->getMemProt() << " vs " << Prot;
383
return make_error<JITLinkError>(std::move(ErrMsg));
384
}
385
386
Block *B = nullptr;
387
if (Sec.sh_type != ELF::SHT_NOBITS) {
388
auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
389
if (!Data)
390
return Data.takeError();
391
392
B = &G->createContentBlock(*GraphSec, *Data,
393
orc::ExecutorAddr(Sec.sh_addr),
394
Sec.sh_addralign, 0);
395
} else
396
B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
397
orc::ExecutorAddr(Sec.sh_addr),
398
Sec.sh_addralign, 0);
399
400
if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
401
// Add live symbol to avoid dead-stripping for .ARM.exidx sections
402
G->addAnonymousSymbol(*B, orc::ExecutorAddrDiff(),
403
orc::ExecutorAddrDiff(), false, true);
404
}
405
406
setGraphBlock(SecIndex, B);
407
}
408
409
return Error::success();
410
}
411
412
template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
413
LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
414
415
// No SYMTAB -- Bail out early.
416
if (!SymTabSec)
417
return Error::success();
418
419
// Get the section content as a Symbols array.
420
auto Symbols = Obj.symbols(SymTabSec);
421
if (!Symbols)
422
return Symbols.takeError();
423
424
// Get the string table for this section.
425
auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
426
if (!StringTab)
427
return StringTab.takeError();
428
429
LLVM_DEBUG({
430
StringRef SymTabName;
431
432
if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
433
SymTabName = *SymTabNameOrErr;
434
else {
435
dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
436
<< toString(SymTabNameOrErr.takeError()) << "\n";
437
SymTabName = "<SHT_SYMTAB section with invalid name>";
438
}
439
440
dbgs() << " Adding symbols from symtab section \"" << SymTabName
441
<< "\"\n";
442
});
443
444
for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
445
auto &Sym = (*Symbols)[SymIndex];
446
447
// Check symbol type.
448
switch (Sym.getType()) {
449
case ELF::STT_FILE:
450
LLVM_DEBUG({
451
if (auto Name = Sym.getName(*StringTab))
452
dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""
453
<< *Name << "\"\n";
454
else {
455
dbgs() << "Could not get STT_FILE symbol name: "
456
<< toString(Name.takeError()) << "\n";
457
dbgs() << " " << SymIndex
458
<< ": Skipping STT_FILE symbol with invalid name\n";
459
}
460
});
461
continue;
462
break;
463
}
464
465
// Get the symbol name.
466
auto Name = Sym.getName(*StringTab);
467
if (!Name)
468
return Name.takeError();
469
470
// Handle common symbols specially.
471
if (Sym.isCommon()) {
472
Symbol &GSym = G->addDefinedSymbol(
473
G->createZeroFillBlock(getCommonSection(), Sym.st_size,
474
orc::ExecutorAddr(), Sym.getValue(), 0),
475
0, *Name, Sym.st_size, Linkage::Strong, Scope::Default, false, false);
476
setGraphSymbol(SymIndex, GSym);
477
continue;
478
}
479
480
if (Sym.isDefined() &&
481
(Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
482
Sym.getType() == ELF::STT_OBJECT ||
483
Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
484
485
// Map Visibility and Binding to Scope and Linkage:
486
Linkage L;
487
Scope S;
488
if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
489
std::tie(L, S) = *LSOrErr;
490
else
491
return LSOrErr.takeError();
492
493
// Handle extended tables.
494
unsigned Shndx = Sym.st_shndx;
495
if (Shndx == ELF::SHN_XINDEX) {
496
auto ShndxTable = ShndxTables.find(SymTabSec);
497
if (ShndxTable == ShndxTables.end())
498
continue;
499
auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
500
Sym, SymIndex, ShndxTable->second);
501
if (!NdxOrErr)
502
return NdxOrErr.takeError();
503
Shndx = *NdxOrErr;
504
}
505
if (auto *B = getGraphBlock(Shndx)) {
506
LLVM_DEBUG({
507
dbgs() << " " << SymIndex
508
<< ": Creating defined graph symbol for ELF symbol \"" << *Name
509
<< "\"\n";
510
});
511
512
TargetFlagsType Flags = makeTargetFlags(Sym);
513
orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);
514
515
if (Offset + Sym.st_size > B->getSize()) {
516
std::string ErrMsg;
517
raw_string_ostream ErrStream(ErrMsg);
518
ErrStream << "In " << G->getName() << ", symbol ";
519
if (!Name->empty())
520
ErrStream << *Name;
521
else
522
ErrStream << "<anon>";
523
ErrStream << " (" << (B->getAddress() + Offset) << " -- "
524
<< (B->getAddress() + Offset + Sym.st_size) << ") extends "
525
<< formatv("{0:x}", Offset + Sym.st_size - B->getSize())
526
<< " bytes past the end of its containing block ("
527
<< B->getRange() << ")";
528
return make_error<JITLinkError>(std::move(ErrMsg));
529
}
530
531
// In RISCV, temporary symbols (Used to generate dwarf, eh_frame
532
// sections...) will appear in object code's symbol table, and LLVM does
533
// not use names on these temporary symbols (RISCV gnu toolchain uses
534
// names on these temporary symbols). If the symbol is unnamed, add an
535
// anonymous symbol.
536
auto &GSym =
537
Name->empty()
538
? G->addAnonymousSymbol(*B, Offset, Sym.st_size,
539
false, false)
540
: G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,
541
S, Sym.getType() == ELF::STT_FUNC,
542
false);
543
544
GSym.setTargetFlags(Flags);
545
setGraphSymbol(SymIndex, GSym);
546
}
547
} else if (Sym.isUndefined() && Sym.isExternal()) {
548
LLVM_DEBUG({
549
dbgs() << " " << SymIndex
550
<< ": Creating external graph symbol for ELF symbol \"" << *Name
551
<< "\"\n";
552
});
553
554
if (Sym.getBinding() != ELF::STB_GLOBAL &&
555
Sym.getBinding() != ELF::STB_WEAK)
556
return make_error<StringError>(
557
"Invalid symbol binding " +
558
Twine(static_cast<int>(Sym.getBinding())) +
559
" for external symbol " + *Name,
560
inconvertibleErrorCode());
561
562
// If L is Linkage::Weak that means this is a weakly referenced symbol.
563
auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
564
Sym.getBinding() == ELF::STB_WEAK);
565
setGraphSymbol(SymIndex, GSym);
566
} else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&
567
Sym.getType() == ELF::STT_NOTYPE &&
568
Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {
569
// Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and
570
// use this kind of null symbol as a placeholder.
571
LLVM_DEBUG({
572
dbgs() << " " << SymIndex << ": Creating null graph symbol\n";
573
});
574
575
auto SymName =
576
G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));
577
auto SymNameRef = StringRef(SymName.data(), SymName.size());
578
auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,
579
Linkage::Strong, Scope::Local, false);
580
setGraphSymbol(SymIndex, GSym);
581
} else {
582
LLVM_DEBUG({
583
dbgs() << " " << SymIndex
584
<< ": Not creating graph symbol for ELF symbol \"" << *Name
585
<< "\" with unrecognized type\n";
586
});
587
}
588
}
589
590
return Error::success();
591
}
592
593
template <typename ELFT>
594
template <typename RelocHandlerFunction>
595
Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation(
596
const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
597
// Only look into sections that store relocation entries.
598
if (RelSect.sh_type != ELF::SHT_RELA)
599
return Error::success();
600
601
// sh_info contains the section header index of the target (FixupSection),
602
// which is the section to which all relocations in RelSect apply.
603
auto FixupSection = Obj.getSection(RelSect.sh_info);
604
if (!FixupSection)
605
return FixupSection.takeError();
606
607
// Target sections have names in valid ELF object files.
608
Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
609
if (!Name)
610
return Name.takeError();
611
LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
612
613
// Consider skipping these relocations.
614
if (!ProcessDebugSections && isDwarfSection(*Name)) {
615
LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
616
return Error::success();
617
}
618
if (excludeSection(**FixupSection)) {
619
LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
620
return Error::success();
621
}
622
623
// Lookup the link-graph node corresponding to the target section name.
624
auto *BlockToFix = getGraphBlock(RelSect.sh_info);
625
if (!BlockToFix)
626
return make_error<StringError>(
627
"Refencing a section that wasn't added to the graph: " + *Name,
628
inconvertibleErrorCode());
629
630
auto RelEntries = Obj.relas(RelSect);
631
if (!RelEntries)
632
return RelEntries.takeError();
633
634
// Let the callee process relocation entries one by one.
635
for (const typename ELFT::Rela &R : *RelEntries)
636
if (Error Err = Func(R, **FixupSection, *BlockToFix))
637
return Err;
638
639
LLVM_DEBUG(dbgs() << "\n");
640
return Error::success();
641
}
642
643
template <typename ELFT>
644
template <typename RelocHandlerFunction>
645
Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation(
646
const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
647
// Only look into sections that store relocation entries.
648
if (RelSect.sh_type != ELF::SHT_REL)
649
return Error::success();
650
651
// sh_info contains the section header index of the target (FixupSection),
652
// which is the section to which all relocations in RelSect apply.
653
auto FixupSection = Obj.getSection(RelSect.sh_info);
654
if (!FixupSection)
655
return FixupSection.takeError();
656
657
// Target sections have names in valid ELF object files.
658
Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
659
if (!Name)
660
return Name.takeError();
661
LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
662
663
// Consider skipping these relocations.
664
if (!ProcessDebugSections && isDwarfSection(*Name)) {
665
LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
666
return Error::success();
667
}
668
if (excludeSection(**FixupSection)) {
669
LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
670
return Error::success();
671
}
672
673
// Lookup the link-graph node corresponding to the target section name.
674
auto *BlockToFix = getGraphBlock(RelSect.sh_info);
675
if (!BlockToFix)
676
return make_error<StringError>(
677
"Refencing a section that wasn't added to the graph: " + *Name,
678
inconvertibleErrorCode());
679
680
auto RelEntries = Obj.rels(RelSect);
681
if (!RelEntries)
682
return RelEntries.takeError();
683
684
// Let the callee process relocation entries one by one.
685
for (const typename ELFT::Rel &R : *RelEntries)
686
if (Error Err = Func(R, **FixupSection, *BlockToFix))
687
return Err;
688
689
LLVM_DEBUG(dbgs() << "\n");
690
return Error::success();
691
}
692
693
} // end namespace jitlink
694
} // end namespace llvm
695
696
#undef DEBUG_TYPE
697
698
#endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
699
700