Skip to content

Commit a94060c

Browse files
committed
[ELF] Pass Ctx & to Relocations
1 parent 2a005bf commit a94060c

File tree

3 files changed

+54
-43
lines changed

3 files changed

+54
-43
lines changed

lld/ELF/Relocations.cpp

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,12 @@ class OffsetGetter {
459459
// InputSectionBase.
460460
class RelocationScanner {
461461
public:
462+
RelocationScanner(Ctx &ctx) : ctx(ctx) {}
462463
template <class ELFT>
463464
void scanSection(InputSectionBase &s, bool isEH = false);
464465

465466
private:
467+
Ctx &ctx;
466468
InputSectionBase *sec;
467469
OffsetGetter getter;
468470

@@ -476,6 +478,9 @@ class RelocationScanner {
476478
uint64_t relOff) const;
477479
void processAux(RelExpr expr, RelType type, uint64_t offset, Symbol &sym,
478480
int64_t addend) const;
481+
unsigned handleTlsRelocation(RelExpr expr, RelType type, uint64_t offset,
482+
Symbol &sym, int64_t addend);
483+
479484
template <class ELFT, class RelTy>
480485
void scanOne(typename Relocs<RelTy>::const_iterator &i);
481486
template <class ELFT, class RelTy> void scan(Relocs<RelTy> rels);
@@ -1294,20 +1299,21 @@ static unsigned handleMipsTlsRelocation(RelType type, Symbol &sym,
12941299
// symbol in TLS block.
12951300
//
12961301
// Returns the number of relocations processed.
1297-
static unsigned handleTlsRelocation(RelType type, Symbol &sym,
1298-
InputSectionBase &c, uint64_t offset,
1299-
int64_t addend, RelExpr expr) {
1302+
unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
1303+
uint64_t offset, Symbol &sym,
1304+
int64_t addend) {
13001305
if (expr == R_TPREL || expr == R_TPREL_NEG) {
13011306
if (ctx.arg.shared) {
13021307
errorOrWarn("relocation " + toString(type) + " against " + toString(sym) +
1303-
" cannot be used with -shared" + getLocation(c, sym, offset));
1308+
" cannot be used with -shared" +
1309+
getLocation(*sec, sym, offset));
13041310
return 1;
13051311
}
13061312
return 0;
13071313
}
13081314

13091315
if (ctx.arg.emachine == EM_MIPS)
1310-
return handleMipsTlsRelocation(type, sym, c, offset, addend, expr);
1316+
return handleMipsTlsRelocation(type, sym, *sec, offset, addend, expr);
13111317

13121318
// LoongArch does not yet implement transition from TLSDESC to LE/IE, so
13131319
// generate TLSDESC dynamic relocation for the dynamic linker to handle.
@@ -1316,7 +1322,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13161322
R_TLSDESC_CALL>(expr)) {
13171323
if (expr != R_TLSDESC_CALL) {
13181324
sym.setFlags(NEEDS_TLSDESC);
1319-
c.addReloc({expr, type, offset, addend, &sym});
1325+
sec->addReloc({expr, type, offset, addend, &sym});
13201326
}
13211327
return 1;
13221328
}
@@ -1331,7 +1337,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13311337
if (expr != R_TLSDESC_CALL) {
13321338
if (!isRISCV || type == R_RISCV_TLSDESC_HI20)
13331339
sym.setFlags(NEEDS_TLSDESC);
1334-
c.addReloc({expr, type, offset, addend, &sym});
1340+
sec->addReloc({expr, type, offset, addend, &sym});
13351341
}
13361342
return 1;
13371343
}
@@ -1345,10 +1351,11 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13451351
!ctx.arg.shared && ctx.arg.emachine != EM_ARM &&
13461352
ctx.arg.emachine != EM_HEXAGON && ctx.arg.emachine != EM_LOONGARCH &&
13471353
!(isRISCV && expr != R_TLSDESC_PC && expr != R_TLSDESC_CALL) &&
1348-
!c.file->ppc64DisableTLSRelax;
1354+
!sec->file->ppc64DisableTLSRelax;
13491355

13501356
// If we are producing an executable and the symbol is non-preemptable, it
1351-
// must be defined and the code sequence can be optimized to use Local-Exec.
1357+
// must be defined and the code sequence can be optimized to use
1358+
// Local-Exesec->
13521359
//
13531360
// ARM and RISC-V do not support any relaxations for TLS relocations, however,
13541361
// we can omit the DTPMOD dynamic relocations and resolve them at link time
@@ -1361,33 +1368,33 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13611368
// module index, with a special value of 0 for the current module. GOT[e1] is
13621369
// unused. There only needs to be one module index entry.
13631370
if (oneof<R_TLSLD_GOT, R_TLSLD_GOTPLT, R_TLSLD_PC, R_TLSLD_HINT>(expr)) {
1364-
// Local-Dynamic relocs can be optimized to Local-Exec.
1371+
// Local-Dynamic relocs can be optimized to Local-Exesec->
13651372
if (execOptimize) {
1366-
c.addReloc({ctx.target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE), type,
1367-
offset, addend, &sym});
1373+
sec->addReloc({ctx.target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE),
1374+
type, offset, addend, &sym});
13681375
return ctx.target->getTlsGdRelaxSkip(type);
13691376
}
13701377
if (expr == R_TLSLD_HINT)
13711378
return 1;
13721379
ctx.needsTlsLd.store(true, std::memory_order_relaxed);
1373-
c.addReloc({expr, type, offset, addend, &sym});
1380+
sec->addReloc({expr, type, offset, addend, &sym});
13741381
return 1;
13751382
}
13761383

1377-
// Local-Dynamic relocs can be optimized to Local-Exec.
1384+
// Local-Dynamic relocs can be optimized to Local-Exesec->
13781385
if (expr == R_DTPREL) {
13791386
if (execOptimize)
13801387
expr = ctx.target->adjustTlsExpr(type, R_RELAX_TLS_LD_TO_LE);
1381-
c.addReloc({expr, type, offset, addend, &sym});
1388+
sec->addReloc({expr, type, offset, addend, &sym});
13821389
return 1;
13831390
}
13841391

13851392
// Local-Dynamic sequence where offset of tls variable relative to dynamic
13861393
// thread pointer is stored in the got. This cannot be optimized to
1387-
// Local-Exec.
1394+
// Local-Exesec->
13881395
if (expr == R_TLSLD_GOT_OFF) {
13891396
sym.setFlags(NEEDS_GOT_DTPREL);
1390-
c.addReloc({expr, type, offset, addend, &sym});
1397+
sec->addReloc({expr, type, offset, addend, &sym});
13911398
return 1;
13921399
}
13931400

@@ -1396,7 +1403,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13961403
R_LOONGARCH_TLSGD_PAGE_PC>(expr)) {
13971404
if (!execOptimize) {
13981405
sym.setFlags(NEEDS_TLSGD);
1399-
c.addReloc({expr, type, offset, addend, &sym});
1406+
sec->addReloc({expr, type, offset, addend, &sym});
14001407
return 1;
14011408
}
14021409

@@ -1405,14 +1412,14 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
14051412
//
14061413
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference a non-preemptible
14071414
// label, so TLSDESC=>IE will be categorized as R_RELAX_TLS_GD_TO_LE. We fix
1408-
// the categorization in RISCV::relocateAlloc.
1415+
// the categorization in RISCV::relocateAllosec->
14091416
if (sym.isPreemptible) {
14101417
sym.setFlags(NEEDS_TLSGD_TO_IE);
1411-
c.addReloc({ctx.target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type,
1412-
offset, addend, &sym});
1418+
sec->addReloc({ctx.target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE),
1419+
type, offset, addend, &sym});
14131420
} else {
1414-
c.addReloc({ctx.target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_LE), type,
1415-
offset, addend, &sym});
1421+
sec->addReloc({ctx.target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_LE),
1422+
type, offset, addend, &sym});
14161423
}
14171424
return ctx.target->getTlsGdRelaxSkip(type);
14181425
}
@@ -1423,15 +1430,15 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
14231430
// Initial-Exec relocs can be optimized to Local-Exec if the symbol is
14241431
// locally defined. This is not supported on SystemZ.
14251432
if (execOptimize && isLocalInExecutable && ctx.arg.emachine != EM_S390) {
1426-
c.addReloc({R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
1433+
sec->addReloc({R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
14271434
} else if (expr != R_TLSIE_HINT) {
14281435
sym.setFlags(NEEDS_TLSIE);
14291436
// R_GOT needs a relative relocation for PIC on i386 and Hexagon.
14301437
if (expr == R_GOT && ctx.arg.isPic &&
14311438
!ctx.target->usesOnlyLowPageBits(type))
1432-
addRelativeReloc<true>(c, offset, sym, addend, expr, type);
1439+
addRelativeReloc<true>(*sec, offset, sym, addend, expr, type);
14331440
else
1434-
c.addReloc({expr, type, offset, addend, &sym});
1441+
sec->addReloc({expr, type, offset, addend, &sym});
14351442
}
14361443
return 1;
14371444
}
@@ -1539,7 +1546,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
15391546
// but we need to process them in handleTlsRelocation.
15401547
if (sym.isTls() || oneof<R_TLSDESC_PC, R_TLSDESC_CALL>(expr)) {
15411548
if (unsigned processed =
1542-
handleTlsRelocation(type, sym, *sec, offset, addend, expr)) {
1549+
handleTlsRelocation(expr, type, offset, sym, addend)) {
15431550
i += processed - 1;
15441551
return;
15451552
}
@@ -1635,7 +1642,7 @@ void RelocationScanner::scanSection(InputSectionBase &s, bool isEH) {
16351642
scan<ELFT>(rels.relas);
16361643
}
16371644

1638-
template <class ELFT> void elf::scanRelocations() {
1645+
template <class ELFT> void elf::scanRelocations(Ctx &ctx) {
16391646
// Scan all relocations. Each relocation goes through a series of tests to
16401647
// determine if it needs special treatment, such as creating GOT, PLT,
16411648
// copy relocations, etc. Note that relocations for non-alloc sections are
@@ -1649,8 +1656,8 @@ template <class ELFT> void elf::scanRelocations() {
16491656
parallel::TaskGroup tg;
16501657
auto outerFn = [&]() {
16511658
for (ELFFileBase *f : ctx.objectFiles) {
1652-
auto fn = [f]() {
1653-
RelocationScanner scanner;
1659+
auto fn = [f, &ctx]() {
1660+
RelocationScanner scanner(ctx);
16541661
for (InputSectionBase *s : f->getSections()) {
16551662
if (s && s->kind() == SectionBase::Regular && s->isLive() &&
16561663
(s->flags & SHF_ALLOC) &&
@@ -1663,8 +1670,8 @@ template <class ELFT> void elf::scanRelocations() {
16631670
else
16641671
tg.spawn(fn);
16651672
}
1666-
auto scanEH = [] {
1667-
RelocationScanner scanner;
1673+
auto scanEH = [&] {
1674+
RelocationScanner scanner(ctx);
16681675
for (Partition &part : ctx.partitions) {
16691676
for (EhInputSection *sec : part.ehFrame->sections)
16701677
scanner.template scanSection<ELFT>(*sec, /*isEH=*/true);
@@ -1771,8 +1778,8 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
17711778
return true;
17721779
}
17731780

1774-
void elf::postScanRelocations() {
1775-
auto fn = [](Symbol &sym) {
1781+
void elf::postScanRelocations(Ctx &ctx) {
1782+
auto fn = [&](Symbol &sym) {
17761783
auto flags = sym.flags.load(std::memory_order_relaxed);
17771784
if (handleNonPreemptibleIfunc(sym, flags))
17781785
return;
@@ -2453,10 +2460,10 @@ template <class ELFT> void elf::checkNoCrossRefs() {
24532460
}
24542461
}
24552462

2456-
template void elf::scanRelocations<ELF32LE>();
2457-
template void elf::scanRelocations<ELF32BE>();
2458-
template void elf::scanRelocations<ELF64LE>();
2459-
template void elf::scanRelocations<ELF64BE>();
2463+
template void elf::scanRelocations<ELF32LE>(Ctx &);
2464+
template void elf::scanRelocations<ELF32BE>(Ctx &);
2465+
template void elf::scanRelocations<ELF64LE>(Ctx &);
2466+
template void elf::scanRelocations<ELF64BE>(Ctx &);
24602467

24612468
template void elf::checkNoCrossRefs<ELF32LE>();
24622469
template void elf::checkNoCrossRefs<ELF32BE>();

lld/ELF/Relocations.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <vector>
1717

1818
namespace lld::elf {
19+
struct Ctx;
1920
class Symbol;
2021
class InputSection;
2122
class InputSectionBase;
@@ -141,10 +142,10 @@ struct JumpInstrMod {
141142
// This function writes undefined symbol diagnostics to an internal buffer.
142143
// Call reportUndefinedSymbols() after calling scanRelocations() to emit
143144
// the diagnostics.
144-
template <class ELFT> void scanRelocations();
145+
template <class ELFT> void scanRelocations(Ctx &ctx);
145146
template <class ELFT> void checkNoCrossRefs();
146147
void reportUndefinedSymbols();
147-
void postScanRelocations();
148+
void postScanRelocations(Ctx &ctx);
148149
void addGotEntry(Symbol &sym);
149150

150151
void hexagonTLSSymbolUpdate(ArrayRef<OutputSection *> outputSections);
@@ -156,6 +157,7 @@ class InputSectionDescription;
156157

157158
class ThunkCreator {
158159
public:
160+
ThunkCreator(Ctx &ctx) : ctx(ctx) {}
159161
// Return true if Thunks have been added to OutputSections
160162
bool createThunks(uint32_t pass, ArrayRef<OutputSection *> outputSections);
161163

@@ -178,6 +180,8 @@ class ThunkCreator {
178180

179181
bool normalizeExistingThunk(Relocation &rel, uint64_t src);
180182

183+
Ctx &ctx;
184+
181185
// Record all the available Thunks for a (Symbol, addend) pair, where Symbol
182186
// is represented as a (section, offset) pair. There may be multiple
183187
// relocations sharing the same (section, offset + addend) pair. We may revert

lld/ELF/Writer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,7 +1435,7 @@ static void finalizeSynthetic(SyntheticSection *sec) {
14351435
// in Writer<ELFT>::finalizeSections().
14361436
template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
14371437
llvm::TimeTraceScope timeScope("Finalize address dependent content");
1438-
ThunkCreator tc;
1438+
ThunkCreator tc(ctx);
14391439
AArch64Err843419Patcher a64p;
14401440
ARMErr657417Patcher a32p;
14411441
ctx.script->assignAddresses();
@@ -1804,9 +1804,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
18041804
// that we can correctly decide if a dynamic relocation is needed. This is
18051805
// called after processSymbolAssignments() because it needs to know whether
18061806
// a linker-script-defined symbol is absolute.
1807-
scanRelocations<ELFT>();
1807+
scanRelocations<ELFT>(ctx);
18081808
reportUndefinedSymbols();
1809-
postScanRelocations();
1809+
postScanRelocations(ctx);
18101810

18111811
if (ctx.in.plt && ctx.in.plt->isNeeded())
18121812
ctx.in.plt->addSymbols();

0 commit comments

Comments
 (0)