Skip to content

Commit 29783f7

Browse files
committed
[ELF] Pass Ctx & to Relocations
1 parent d30d251 commit 29783f7

File tree

7 files changed

+50
-48
lines changed

7 files changed

+50
-48
lines changed

lld/ELF/Arch/SystemZ.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ bool SystemZ::relaxOnce(int pass) const {
453453
continue;
454454
if (rel.sym->auxIdx == 0) {
455455
rel.sym->allocateAux();
456-
addGotEntry(*rel.sym);
456+
addGotEntry(ctx, *rel.sym);
457457
changed = true;
458458
}
459459
rel.expr = R_GOT_PC;

lld/ELF/Arch/X86_64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ bool X86_64::relaxOnce(int pass) const {
339339
continue;
340340
if (rel.sym->auxIdx == 0) {
341341
rel.sym->allocateAux();
342-
addGotEntry(*rel.sym);
342+
addGotEntry(ctx, *rel.sym);
343343
changed = true;
344344
}
345345
rel.expr = R_GOT_PC;

lld/ELF/Relocations.cpp

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,20 @@ using namespace llvm::support::endian;
6565
using namespace lld;
6666
using namespace lld::elf;
6767

68-
static std::optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
68+
static std::optional<std::string> getLinkerScriptLocation(Ctx &ctx,
69+
const Symbol &sym) {
6970
for (SectionCommand *cmd : ctx.script->sectionCommands)
7071
if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
7172
if (assign->sym == &sym)
7273
return assign->location;
7374
return std::nullopt;
7475
}
7576

76-
static std::string getDefinedLocation(const Symbol &sym) {
77+
static std::string getDefinedLocation(Ctx &ctx, const Symbol &sym) {
7778
const char msg[] = "\n>>> defined in ";
7879
if (sym.file)
7980
return msg + toString(sym.file);
80-
if (std::optional<std::string> loc = getLinkerScriptLocation(sym))
81+
if (std::optional<std::string> loc = getLinkerScriptLocation(ctx, sym))
8182
return msg + *loc;
8283
return "";
8384
}
@@ -87,9 +88,9 @@ static std::string getDefinedLocation(const Symbol &sym) {
8788
// >>> defined in /home/alice/src/foo.o
8889
// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
8990
// >>> /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,
9192
uint64_t off) {
92-
std::string msg = getDefinedLocation(sym) + "\n>>> referenced by ";
93+
std::string msg = getDefinedLocation(ctx, sym) + "\n>>> referenced by ";
9394
std::string src = s.getSrcMsg(sym, off);
9495
if (!src.empty())
9596
msg += src + "\n>>> ";
@@ -116,7 +117,7 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
116117
if (!errPlace.srcLoc.empty())
117118
hint += "\n>>> referenced by " + errPlace.srcLoc;
118119
if (rel.sym && !rel.sym->isSection())
119-
hint += getDefinedLocation(*rel.sym);
120+
hint += getDefinedLocation(ctx, *rel.sym);
120121

121122
if (errPlace.isec && errPlace.isec->name.starts_with(".debug"))
122123
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,
127128
", " + Twine(max).str() + "]" + hint);
128129
}
129130

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) {
132133
ErrorPlace errPlace = getErrorPlace(loc);
133134
std::string hint;
134135
if (!sym.getName().empty())
135-
hint =
136-
"; references '" + lld::toString(sym) + '\'' + getDefinedLocation(sym);
136+
hint = "; references '" + lld::toString(sym) + '\'' +
137+
getDefinedLocation(ctx, sym);
137138
errorOrWarn(errPlace.loc + msg + " is out of range: " + Twine(v) +
138139
" is not in [" + Twine(llvm::minIntN(n)) + ", " +
139140
Twine(llvm::maxIntN(n)) + "]" + hint);
@@ -926,7 +927,7 @@ static void addPltEntry(PltSection &plt, GotPltSection &gotPlt,
926927
sym, 0, R_ABS});
927928
}
928929

929-
void elf::addGotEntry(Symbol &sym) {
930+
void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
930931
ctx.in.got->addEntry(sym);
931932
uint64_t off = sym.getGotOffset();
932933

@@ -960,7 +961,7 @@ static void addTpOffsetGotEntry(Symbol &sym) {
960961
// Return true if we can define a symbol in the executable that
961962
// contains the value/function of a symbol defined in a shared
962963
// library.
963-
static bool canDefineSymbolInExecutable(Symbol &sym) {
964+
static bool canDefineSymbolInExecutable(Ctx &ctx, Symbol &sym) {
964965
// If the symbol has default visibility the symbol defined in the
965966
// executable will preempt it.
966967
// Note that we want the visibility of the shared symbol itself, not
@@ -1041,7 +1042,7 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
10411042
return true;
10421043

10431044
error("relocation " + toString(type) + " cannot refer to absolute symbol: " +
1044-
toString(sym) + getLocation(*sec, sym, relOff));
1045+
toString(sym) + getLocation(ctx, *sec, sym, relOff));
10451046
return true;
10461047
}
10471048

@@ -1206,9 +1207,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12061207
// R_AARCH64_AUTH_ABS64.
12071208
if (!ctx.arg.shared && sym.isShared() &&
12081209
!(ctx.arg.emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
1209-
if (!canDefineSymbolInExecutable(sym)) {
1210+
if (!canDefineSymbolInExecutable(ctx, sym)) {
12101211
errorOrWarn("cannot preempt symbol: " + toString(sym) +
1211-
getLocation(*sec, sym, offset));
1212+
getLocation(ctx, *sec, sym, offset));
12121213
return;
12131214
}
12141215

@@ -1219,7 +1220,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12191220
error("unresolvable relocation " + toString(type) +
12201221
" against symbol '" + toString(*ss) +
12211222
"'; recompile with -fPIC or remove '-z nocopyreloc'" +
1222-
getLocation(*sec, sym, offset));
1223+
getLocation(ctx, *sec, sym, offset));
12231224
sym.setFlags(NEEDS_COPY);
12241225
}
12251226
sec->addReloc({expr, type, offset, addend, &sym});
@@ -1257,7 +1258,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12571258
if (ctx.arg.pie && ctx.arg.emachine == EM_386)
12581259
errorOrWarn("symbol '" + toString(sym) +
12591260
"' cannot be preempted; recompile with -fPIE" +
1260-
getLocation(*sec, sym, offset));
1261+
getLocation(ctx, *sec, sym, offset));
12611262
sym.setFlags(NEEDS_COPY | NEEDS_PLT);
12621263
sec->addReloc({expr, type, offset, addend, &sym});
12631264
return;
@@ -1267,7 +1268,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12671268
errorOrWarn("relocation " + toString(type) + " cannot be used against " +
12681269
(sym.getName().empty() ? "local symbol"
12691270
: "symbol '" + toString(sym) + "'") +
1270-
"; recompile with -fPIC" + getLocation(*sec, sym, offset));
1271+
"; recompile with -fPIC" + getLocation(ctx, *sec, sym, offset));
12711272
}
12721273

12731274
// This function is similar to the `handleTlsRelocation`. MIPS does not
@@ -1306,7 +1307,7 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
13061307
if (ctx.arg.shared) {
13071308
errorOrWarn("relocation " + toString(type) + " against " + toString(sym) +
13081309
" cannot be used with -shared" +
1309-
getLocation(*sec, sym, offset));
1310+
getLocation(ctx, *sec, sym, offset));
13101311
return 1;
13111312
}
13121313
return 0;
@@ -1515,7 +1516,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
15151516
if (i == end) {
15161517
errorOrWarn("R_PPC64_TLSGD/R_PPC64_TLSLD may not be the last "
15171518
"relocation" +
1518-
getLocation(*sec, sym, offset));
1519+
getLocation(ctx, *sec, sym, offset));
15191520
return;
15201521
}
15211522
}
@@ -1694,7 +1695,7 @@ template <class ELFT> void elf::scanRelocations(Ctx &ctx) {
16941695
outerFn();
16951696
}
16961697

1697-
static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
1698+
static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
16981699
// Handle a reference to a non-preemptible ifunc. These are special in a
16991700
// few ways:
17001701
//
@@ -1770,7 +1771,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
17701771
d.type = STT_FUNC;
17711772

17721773
if (flags & NEEDS_GOT)
1773-
addGotEntry(sym);
1774+
addGotEntry(ctx, sym);
17741775
} else if (flags & NEEDS_GOT) {
17751776
// Redirect GOT accesses to point to the Igot.
17761777
sym.gotInIgot = true;
@@ -1781,7 +1782,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
17811782
void elf::postScanRelocations(Ctx &ctx) {
17821783
auto fn = [&](Symbol &sym) {
17831784
auto flags = sym.flags.load(std::memory_order_relaxed);
1784-
if (handleNonPreemptibleIfunc(sym, flags))
1785+
if (handleNonPreemptibleIfunc(ctx, sym, flags))
17851786
return;
17861787

17871788
if (sym.isTagged() && sym.isDefined())
@@ -1792,7 +1793,7 @@ void elf::postScanRelocations(Ctx &ctx) {
17921793
sym.allocateAux();
17931794

17941795
if (flags & NEEDS_GOT)
1795-
addGotEntry(sym);
1796+
addGotEntry(ctx, sym);
17961797
if (flags & NEEDS_PLT)
17971798
addPltEntry(*ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt,
17981799
ctx.target->pltRel, sym);
@@ -2052,7 +2053,7 @@ void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> outputSections) {
20522053
});
20532054
}
20542055

2055-
static int64_t getPCBias(RelType type) {
2056+
static int64_t getPCBias(Ctx &ctx, RelType type) {
20562057
if (ctx.arg.emachine != EM_ARM)
20572058
return 0;
20582059
switch (type) {
@@ -2074,7 +2075,7 @@ ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *os,
20742075
const Relocation &rel,
20752076
uint64_t src) {
20762077
// 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);
20782079
for (std::pair<ThunkSection *, uint32_t> tp : isd->thunkSections) {
20792080
ThunkSection *ts = tp.first;
20802081
uint64_t tsBase = os->addr + ts->outSecOff - pcBias;
@@ -2235,7 +2236,7 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
22352236
// out in the relocation addend. We compensate for the PC bias so that
22362237
// an Arm and Thumb relocation to the same destination get the same keyAddend,
22372238
// which is usually 0.
2238-
const int64_t pcBias = getPCBias(rel.type);
2239+
const int64_t pcBias = getPCBias(ctx, rel.type);
22392240
const int64_t keyAddend = rel.addend + pcBias;
22402241

22412242
// We use a ((section, offset), addend) pair to find the thunk position if
@@ -2357,7 +2358,7 @@ bool ThunkCreator::createThunks(uint32_t pass,
23572358
// STT_SECTION + non-zero addend, clear the addend after
23582359
// redirection.
23592360
if (ctx.arg.emachine != EM_MIPS)
2360-
rel.addend = -getPCBias(rel.type);
2361+
rel.addend = -getPCBias(ctx, rel.type);
23612362
}
23622363

23632364
for (auto &p : isd->thunkSections)
@@ -2390,13 +2391,13 @@ bool elf::hexagonNeedsTLSSymbol(ArrayRef<OutputSection *> outputSections) {
23902391
return needTlsSymbol;
23912392
}
23922393

2393-
void elf::hexagonTLSSymbolUpdate(ArrayRef<OutputSection *> outputSections) {
2394+
void elf::hexagonTLSSymbolUpdate(Ctx &ctx) {
23942395
Symbol *sym = ctx.symtab->find("__tls_get_addr");
23952396
if (!sym)
23962397
return;
23972398
bool needEntry = true;
23982399
forEachInputSectionDescription(
2399-
outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
2400+
ctx.outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
24002401
for (InputSection *isec : isd->sections)
24012402
for (Relocation &rel : isec->relocs())
24022403
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) {
24182419
}
24192420

24202421
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) {
24232424
for (const auto &r : rels) {
24242425
Symbol &sym = sec->file->getSymbol(r.getSymbol(ctx.arg.isMips64EL));
24252426
// A legal cross-reference is when the destination output section is
@@ -2442,7 +2443,7 @@ static void scanCrossRefs(const NoCrossRefCommand &cmd, OutputSection *osec,
24422443

24432444
// For each output section described by at least one NOCROSSREFS(_TO) command,
24442445
// 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) {
24462447
for (OutputSection *osec : ctx.outputSections) {
24472448
for (const NoCrossRefCommand &noxref : ctx.script->noCrossRefs) {
24482449
if (!llvm::is_contained(noxref.outputSections, osec->name) ||
@@ -2453,7 +2454,7 @@ template <class ELFT> void elf::checkNoCrossRefs() {
24532454
if (!isd)
24542455
continue;
24552456
parallelForEach(isd->sections, [&](InputSection *sec) {
2456-
invokeOnRelocs(*sec, scanCrossRefs<ELFT>, noxref, osec, sec);
2457+
invokeOnRelocs(*sec, scanCrossRefs<ELFT>, ctx, noxref, osec, sec);
24572458
});
24582459
}
24592460
}
@@ -2465,7 +2466,7 @@ template void elf::scanRelocations<ELF32BE>(Ctx &);
24652466
template void elf::scanRelocations<ELF64LE>(Ctx &);
24662467
template void elf::scanRelocations<ELF64BE>(Ctx &);
24672468

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 &);

lld/ELF/Relocations.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,12 @@ struct JumpInstrMod {
143143
// Call reportUndefinedSymbols() after calling scanRelocations() to emit
144144
// the diagnostics.
145145
template <class ELFT> void scanRelocations(Ctx &ctx);
146-
template <class ELFT> void checkNoCrossRefs();
146+
template <class ELFT> void checkNoCrossRefs(Ctx &ctx);
147147
void reportUndefinedSymbols();
148148
void postScanRelocations(Ctx &ctx);
149-
void addGotEntry(Symbol &sym);
149+
void addGotEntry(Ctx &ctx, Symbol &sym);
150150

151-
void hexagonTLSSymbolUpdate(ArrayRef<OutputSection *> outputSections);
151+
void hexagonTLSSymbolUpdate(Ctx &ctx);
152152
bool hexagonNeedsTLSSymbol(ArrayRef<OutputSection *> outputSections);
153153

154154
class ThunkSection;

lld/ELF/Target.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ template <class ELFT> bool isMipsPIC(const Defined *sym);
247247

248248
void reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
249249
int64_t min, uint64_t max);
250-
void reportRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym,
251-
const Twine &msg);
250+
void reportRangeError(Ctx &ctx, uint8_t *loc, int64_t v, int n,
251+
const Symbol &sym, const Twine &msg);
252252

253253
// Make sure that V can be represented as an N bit signed integer.
254254
inline void checkInt(uint8_t *loc, int64_t v, int n, const Relocation &rel) {

lld/ELF/Thunks.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,8 @@ void PPC64R12SetupStub::writeTo(uint8_t *buf) {
11991199
int64_t offset = (gotPlt ? destination.getGotPltVA() : destination.getVA()) -
12001200
getThunkTargetSym()->getVA();
12011201
if (!isInt<34>(offset))
1202-
reportRangeError(buf, offset, 34, destination, "R12 setup stub offset");
1202+
reportRangeError(ctx, buf, offset, 34, destination,
1203+
"R12 setup stub offset");
12031204

12041205
int nextInstOffset;
12051206
if (ctx.arg.power10Stubs) {

lld/ELF/Writer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
14541454

14551455
// Converts call x@GDPLT to call __tls_get_addr
14561456
if (ctx.arg.emachine == EM_HEXAGON)
1457-
hexagonTLSSymbolUpdate(ctx.outputSections);
1457+
hexagonTLSSymbolUpdate(ctx);
14581458

14591459
uint32_t pass = 0, assignPasses = 0;
14601460
for (;;) {
@@ -1975,7 +1975,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
19751975

19761976
if (ctx.script->noCrossRefs.size()) {
19771977
llvm::TimeTraceScope timeScope("Check NOCROSSREFS");
1978-
checkNoCrossRefs<ELFT>();
1978+
checkNoCrossRefs<ELFT>(ctx);
19791979
}
19801980

19811981
{

0 commit comments

Comments
 (0)