@@ -65,19 +65,20 @@ using namespace llvm::support::endian;
65
65
using namespace lld ;
66
66
using namespace lld ::elf;
67
67
68
- static std::optional<std::string> getLinkerScriptLocation (const Symbol &sym) {
68
+ static std::optional<std::string> getLinkerScriptLocation (Ctx &ctx,
69
+ const Symbol &sym) {
69
70
for (SectionCommand *cmd : ctx.script ->sectionCommands )
70
71
if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
71
72
if (assign->sym == &sym)
72
73
return assign->location ;
73
74
return std::nullopt;
74
75
}
75
76
76
- static std::string getDefinedLocation (const Symbol &sym) {
77
+ static std::string getDefinedLocation (Ctx &ctx, const Symbol &sym) {
77
78
const char msg[] = " \n >>> defined in " ;
78
79
if (sym.file )
79
80
return msg + toString (sym.file );
80
- if (std::optional<std::string> loc = getLinkerScriptLocation (sym))
81
+ if (std::optional<std::string> loc = getLinkerScriptLocation (ctx, sym))
81
82
return msg + *loc;
82
83
return " " ;
83
84
}
@@ -87,9 +88,9 @@ static std::string getDefinedLocation(const Symbol &sym) {
87
88
// >>> defined in /home/alice/src/foo.o
88
89
// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
89
90
// >>> /home/alice/src/bar.o:(.text+0x1)
90
- static std::string getLocation (InputSectionBase &s, const Symbol &sym,
91
+ static std::string getLocation (Ctx &ctx, InputSectionBase &s, const Symbol &sym,
91
92
uint64_t off) {
92
- std::string msg = getDefinedLocation (sym) + " \n >>> referenced by " ;
93
+ std::string msg = getDefinedLocation (ctx, sym) + " \n >>> referenced by " ;
93
94
std::string src = s.getSrcMsg (sym, off);
94
95
if (!src.empty ())
95
96
msg += src + " \n >>> " ;
@@ -116,7 +117,7 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
116
117
if (!errPlace.srcLoc .empty ())
117
118
hint += " \n >>> referenced by " + errPlace.srcLoc ;
118
119
if (rel.sym && !rel.sym ->isSection ())
119
- hint += getDefinedLocation (*rel.sym );
120
+ hint += getDefinedLocation (ctx, *rel.sym );
120
121
121
122
if (errPlace.isec && errPlace.isec ->name .starts_with (" .debug" ))
122
123
hint += " ; consider recompiling with -fdebug-types-section to reduce size "
@@ -127,13 +128,13 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
127
128
" , " + Twine (max).str () + " ]" + hint);
128
129
}
129
130
130
- void elf::reportRangeError (uint8_t *loc, int64_t v, int n, const Symbol &sym ,
131
- const Twine &msg) {
131
+ void elf::reportRangeError (Ctx &ctx, uint8_t *loc, int64_t v, int n,
132
+ const Symbol &sym, const Twine &msg) {
132
133
ErrorPlace errPlace = getErrorPlace (loc);
133
134
std::string hint;
134
135
if (!sym.getName ().empty ())
135
- hint =
136
- " ; references ' " + lld::toString (sym) + ' \' ' + getDefinedLocation (sym);
136
+ hint = " ; references ' " + lld::toString (sym) + ' \' ' +
137
+ getDefinedLocation (ctx, sym);
137
138
errorOrWarn (errPlace.loc + msg + " is out of range: " + Twine (v) +
138
139
" is not in [" + Twine (llvm::minIntN (n)) + " , " +
139
140
Twine (llvm::maxIntN (n)) + " ]" + hint);
@@ -926,7 +927,7 @@ static void addPltEntry(PltSection &plt, GotPltSection &gotPlt,
926
927
sym, 0 , R_ABS});
927
928
}
928
929
929
- void elf::addGotEntry (Symbol &sym) {
930
+ void elf::addGotEntry (Ctx &ctx, Symbol &sym) {
930
931
ctx.in .got ->addEntry (sym);
931
932
uint64_t off = sym.getGotOffset ();
932
933
@@ -960,7 +961,7 @@ static void addTpOffsetGotEntry(Symbol &sym) {
960
961
// Return true if we can define a symbol in the executable that
961
962
// contains the value/function of a symbol defined in a shared
962
963
// library.
963
- static bool canDefineSymbolInExecutable (Symbol &sym) {
964
+ static bool canDefineSymbolInExecutable (Ctx &ctx, Symbol &sym) {
964
965
// If the symbol has default visibility the symbol defined in the
965
966
// executable will preempt it.
966
967
// Note that we want the visibility of the shared symbol itself, not
@@ -1041,7 +1042,7 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
1041
1042
return true ;
1042
1043
1043
1044
error (" relocation " + toString (type) + " cannot refer to absolute symbol: " +
1044
- toString (sym) + getLocation (*sec, sym, relOff));
1045
+ toString (sym) + getLocation (ctx, *sec, sym, relOff));
1045
1046
return true ;
1046
1047
}
1047
1048
@@ -1206,9 +1207,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
1206
1207
// R_AARCH64_AUTH_ABS64.
1207
1208
if (!ctx.arg .shared && sym.isShared () &&
1208
1209
!(ctx.arg .emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
1209
- if (!canDefineSymbolInExecutable (sym)) {
1210
+ if (!canDefineSymbolInExecutable (ctx, sym)) {
1210
1211
errorOrWarn (" cannot preempt symbol: " + toString (sym) +
1211
- getLocation (*sec, sym, offset));
1212
+ getLocation (ctx, *sec, sym, offset));
1212
1213
return ;
1213
1214
}
1214
1215
@@ -1219,7 +1220,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
1219
1220
error (" unresolvable relocation " + toString (type) +
1220
1221
" against symbol '" + toString (*ss) +
1221
1222
" '; recompile with -fPIC or remove '-z nocopyreloc'" +
1222
- getLocation (*sec, sym, offset));
1223
+ getLocation (ctx, *sec, sym, offset));
1223
1224
sym.setFlags (NEEDS_COPY);
1224
1225
}
1225
1226
sec->addReloc ({expr, type, offset, addend, &sym});
@@ -1257,7 +1258,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
1257
1258
if (ctx.arg .pie && ctx.arg .emachine == EM_386)
1258
1259
errorOrWarn (" symbol '" + toString (sym) +
1259
1260
" ' cannot be preempted; recompile with -fPIE" +
1260
- getLocation (*sec, sym, offset));
1261
+ getLocation (ctx, *sec, sym, offset));
1261
1262
sym.setFlags (NEEDS_COPY | NEEDS_PLT);
1262
1263
sec->addReloc ({expr, type, offset, addend, &sym});
1263
1264
return ;
@@ -1267,7 +1268,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
1267
1268
errorOrWarn (" relocation " + toString (type) + " cannot be used against " +
1268
1269
(sym.getName ().empty () ? " local symbol"
1269
1270
: " symbol '" + toString (sym) + " '" ) +
1270
- " ; recompile with -fPIC" + getLocation (*sec, sym, offset));
1271
+ " ; recompile with -fPIC" + getLocation (ctx, *sec, sym, offset));
1271
1272
}
1272
1273
1273
1274
// This function is similar to the `handleTlsRelocation`. MIPS does not
@@ -1306,7 +1307,7 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
1306
1307
if (ctx.arg .shared ) {
1307
1308
errorOrWarn (" relocation " + toString (type) + " against " + toString (sym) +
1308
1309
" cannot be used with -shared" +
1309
- getLocation (*sec, sym, offset));
1310
+ getLocation (ctx, *sec, sym, offset));
1310
1311
return 1 ;
1311
1312
}
1312
1313
return 0 ;
@@ -1515,7 +1516,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
1515
1516
if (i == end) {
1516
1517
errorOrWarn (" R_PPC64_TLSGD/R_PPC64_TLSLD may not be the last "
1517
1518
" relocation" +
1518
- getLocation (*sec, sym, offset));
1519
+ getLocation (ctx, *sec, sym, offset));
1519
1520
return ;
1520
1521
}
1521
1522
}
@@ -1694,7 +1695,7 @@ template <class ELFT> void elf::scanRelocations(Ctx &ctx) {
1694
1695
outerFn ();
1695
1696
}
1696
1697
1697
- static bool handleNonPreemptibleIfunc (Symbol &sym, uint16_t flags) {
1698
+ static bool handleNonPreemptibleIfunc (Ctx &ctx, Symbol &sym, uint16_t flags) {
1698
1699
// Handle a reference to a non-preemptible ifunc. These are special in a
1699
1700
// few ways:
1700
1701
//
@@ -1770,7 +1771,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
1770
1771
d.type = STT_FUNC;
1771
1772
1772
1773
if (flags & NEEDS_GOT)
1773
- addGotEntry (sym);
1774
+ addGotEntry (ctx, sym);
1774
1775
} else if (flags & NEEDS_GOT) {
1775
1776
// Redirect GOT accesses to point to the Igot.
1776
1777
sym.gotInIgot = true ;
@@ -1781,7 +1782,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
1781
1782
void elf::postScanRelocations (Ctx &ctx) {
1782
1783
auto fn = [&](Symbol &sym) {
1783
1784
auto flags = sym.flags .load (std::memory_order_relaxed);
1784
- if (handleNonPreemptibleIfunc (sym, flags))
1785
+ if (handleNonPreemptibleIfunc (ctx, sym, flags))
1785
1786
return ;
1786
1787
1787
1788
if (sym.isTagged () && sym.isDefined ())
@@ -1792,7 +1793,7 @@ void elf::postScanRelocations(Ctx &ctx) {
1792
1793
sym.allocateAux ();
1793
1794
1794
1795
if (flags & NEEDS_GOT)
1795
- addGotEntry (sym);
1796
+ addGotEntry (ctx, sym);
1796
1797
if (flags & NEEDS_PLT)
1797
1798
addPltEntry (*ctx.in .plt , *ctx.in .gotPlt , *ctx.in .relaPlt ,
1798
1799
ctx.target ->pltRel , sym);
@@ -2052,7 +2053,7 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> outputSections) {
2052
2053
});
2053
2054
}
2054
2055
2055
- static int64_t getPCBias (RelType type) {
2056
+ static int64_t getPCBias (Ctx &ctx, RelType type) {
2056
2057
if (ctx.arg .emachine != EM_ARM)
2057
2058
return 0 ;
2058
2059
switch (type) {
@@ -2074,7 +2075,7 @@ ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *os,
2074
2075
const Relocation &rel,
2075
2076
uint64_t src) {
2076
2077
// See the comment in getThunk for -pcBias below.
2077
- const int64_t pcBias = getPCBias (rel.type );
2078
+ const int64_t pcBias = getPCBias (ctx, rel.type );
2078
2079
for (std::pair<ThunkSection *, uint32_t > tp : isd->thunkSections ) {
2079
2080
ThunkSection *ts = tp.first ;
2080
2081
uint64_t tsBase = os->addr + ts->outSecOff - pcBias;
@@ -2235,7 +2236,7 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
2235
2236
// out in the relocation addend. We compensate for the PC bias so that
2236
2237
// an Arm and Thumb relocation to the same destination get the same keyAddend,
2237
2238
// which is usually 0.
2238
- const int64_t pcBias = getPCBias (rel.type );
2239
+ const int64_t pcBias = getPCBias (ctx, rel.type );
2239
2240
const int64_t keyAddend = rel.addend + pcBias;
2240
2241
2241
2242
// We use a ((section, offset), addend) pair to find the thunk position if
@@ -2357,7 +2358,7 @@ bool ThunkCreator::createThunks(uint32_t pass,
2357
2358
// STT_SECTION + non-zero addend, clear the addend after
2358
2359
// redirection.
2359
2360
if (ctx.arg .emachine != EM_MIPS)
2360
- rel.addend = -getPCBias (rel.type );
2361
+ rel.addend = -getPCBias (ctx, rel.type );
2361
2362
}
2362
2363
2363
2364
for (auto &p : isd->thunkSections )
@@ -2390,13 +2391,13 @@ bool elf::hexagonNeedsTLSSymbol(ArrayRef<OutputSection *> outputSections) {
2390
2391
return needTlsSymbol;
2391
2392
}
2392
2393
2393
- void elf::hexagonTLSSymbolUpdate (ArrayRef<OutputSection *> outputSections ) {
2394
+ void elf::hexagonTLSSymbolUpdate (Ctx &ctx ) {
2394
2395
Symbol *sym = ctx.symtab ->find (" __tls_get_addr" );
2395
2396
if (!sym)
2396
2397
return ;
2397
2398
bool needEntry = true ;
2398
2399
forEachInputSectionDescription (
2399
- outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
2400
+ ctx. outputSections , [&](OutputSection *os, InputSectionDescription *isd) {
2400
2401
for (InputSection *isec : isd->sections )
2401
2402
for (Relocation &rel : isec->relocs ())
2402
2403
if (rel.sym ->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) {
@@ -2418,8 +2419,8 @@ static bool matchesRefTo(const NoCrossRefCommand &cmd, StringRef osec) {
2418
2419
}
2419
2420
2420
2421
template <class ELFT , class Rels >
2421
- static void scanCrossRefs (const NoCrossRefCommand &cmd, OutputSection *osec ,
2422
- InputSection *sec, Rels rels) {
2422
+ static void scanCrossRefs (Ctx &ctx, const NoCrossRefCommand &cmd,
2423
+ OutputSection *osec, InputSection *sec, Rels rels) {
2423
2424
for (const auto &r : rels) {
2424
2425
Symbol &sym = sec->file ->getSymbol (r.getSymbol (ctx.arg .isMips64EL ));
2425
2426
// A legal cross-reference is when the destination output section is
@@ -2442,7 +2443,7 @@ static void scanCrossRefs(const NoCrossRefCommand &cmd, OutputSection *osec,
2442
2443
2443
2444
// For each output section described by at least one NOCROSSREFS(_TO) command,
2444
2445
// scan relocations from its input sections for prohibited cross references.
2445
- template <class ELFT > void elf::checkNoCrossRefs () {
2446
+ template <class ELFT > void elf::checkNoCrossRefs (Ctx &ctx ) {
2446
2447
for (OutputSection *osec : ctx.outputSections ) {
2447
2448
for (const NoCrossRefCommand &noxref : ctx.script ->noCrossRefs ) {
2448
2449
if (!llvm::is_contained (noxref.outputSections , osec->name ) ||
@@ -2453,7 +2454,7 @@ template <class ELFT> void elf::checkNoCrossRefs() {
2453
2454
if (!isd)
2454
2455
continue ;
2455
2456
parallelForEach (isd->sections , [&](InputSection *sec) {
2456
- invokeOnRelocs (*sec, scanCrossRefs<ELFT>, noxref, osec, sec);
2457
+ invokeOnRelocs (*sec, scanCrossRefs<ELFT>, ctx, noxref, osec, sec);
2457
2458
});
2458
2459
}
2459
2460
}
@@ -2465,7 +2466,7 @@ template void elf::scanRelocations<ELF32BE>(Ctx &);
2465
2466
template void elf::scanRelocations<ELF64LE>(Ctx &);
2466
2467
template void elf::scanRelocations<ELF64BE>(Ctx &);
2467
2468
2468
- template void elf::checkNoCrossRefs<ELF32LE>();
2469
- template void elf::checkNoCrossRefs<ELF32BE>();
2470
- template void elf::checkNoCrossRefs<ELF64LE>();
2471
- template void elf::checkNoCrossRefs<ELF64BE>();
2469
+ template void elf::checkNoCrossRefs<ELF32LE>(Ctx & );
2470
+ template void elf::checkNoCrossRefs<ELF32BE>(Ctx & );
2471
+ template void elf::checkNoCrossRefs<ELF64LE>(Ctx & );
2472
+ template void elf::checkNoCrossRefs<ELF64BE>(Ctx & );
0 commit comments