Skip to content

Commit df0864e

Browse files
committed
[ELF] Move elf::symtab into Ctx
Remove the global variable `symtab` and add a member variable (`std::unique_ptr<SymbolTable>`) to `Ctx` instead. This is one step toward eliminating global states. Pull Request: #109612
1 parent 62f3eae commit df0864e

17 files changed

+127
-126
lines changed

lld/ELF/Arch/ARM.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,7 +1215,7 @@ template <class ELFT> void ObjFile<ELFT>::importCmseSymbols() {
12151215
continue;
12161216
}
12171217

1218-
if (symtab.cmseImportLib.count(sym->getName())) {
1218+
if (ctx.symtab->cmseImportLib.count(sym->getName())) {
12191219
error("CMSE symbol '" + sym->getName() +
12201220
"' is multiply defined in import library '" + toString(this) + "'");
12211221
continue;
@@ -1227,7 +1227,7 @@ template <class ELFT> void ObjFile<ELFT>::importCmseSymbols() {
12271227
Twine(ACLESESYM_SIZE) + " bytes");
12281228
}
12291229

1230-
symtab.cmseImportLib[sym->getName()] = sym;
1230+
ctx.symtab->cmseImportLib[sym->getName()] = sym;
12311231
}
12321232
}
12331233

@@ -1263,9 +1263,9 @@ static std::string checkCmseSymAttributes(Symbol *acleSeSym, Symbol *sym) {
12631263
void elf::processArmCmseSymbols() {
12641264
if (!ctx.arg.cmseImplib)
12651265
return;
1266-
// Only symbols with external linkage end up in symtab, so no need to do
1266+
// Only symbols with external linkage end up in ctx.symtab, so no need to do
12671267
// linkage checks. Only check symbol type.
1268-
for (Symbol *acleSeSym : symtab.getSymbols()) {
1268+
for (Symbol *acleSeSym : ctx.symtab->getSymbols()) {
12691269
if (!acleSeSym->getName().starts_with(ACLESESYM_PREFIX))
12701270
continue;
12711271
// If input object build attributes do not support CMSE, error and disable
@@ -1279,7 +1279,7 @@ void elf::processArmCmseSymbols() {
12791279
// Try to find the associated symbol definition.
12801280
// Symbol must have external linkage.
12811281
StringRef name = acleSeSym->getName().substr(std::strlen(ACLESESYM_PREFIX));
1282-
Symbol *sym = symtab.find(name);
1282+
Symbol *sym = ctx.symtab->find(name);
12831283
if (!sym) {
12841284
error(toString(acleSeSym->file) + ": cmse special symbol '" +
12851285
acleSeSym->getName() +
@@ -1295,7 +1295,7 @@ void elf::processArmCmseSymbols() {
12951295
}
12961296

12971297
// <sym> may be redefined later in the link in .gnu.sgstubs
1298-
symtab.cmseSymMap[name] = {acleSeSym, sym};
1298+
ctx.symtab->cmseSymMap[name] = {acleSeSym, sym};
12991299
}
13001300

13011301
// If this is an Arm CMSE secure app, replace references to entry symbol <sym>
@@ -1304,8 +1304,8 @@ void elf::processArmCmseSymbols() {
13041304
MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
13051305
for (size_t i = 0, e = syms.size(); i != e; ++i) {
13061306
StringRef symName = syms[i]->getName();
1307-
if (symtab.cmseSymMap.count(symName))
1308-
syms[i] = symtab.cmseSymMap[symName].acleSeSym;
1307+
if (ctx.symtab->cmseSymMap.count(symName))
1308+
syms[i] = ctx.symtab->cmseSymMap[symName].acleSeSym;
13091309
}
13101310
});
13111311
}
@@ -1332,26 +1332,26 @@ ArmCmseSGSection::ArmCmseSGSection()
13321332
/*alignment=*/32, ".gnu.sgstubs") {
13331333
entsize = ACLESESYM_SIZE;
13341334
// The range of addresses used in the CMSE import library should be fixed.
1335-
for (auto &[_, sym] : symtab.cmseImportLib) {
1335+
for (auto &[_, sym] : ctx.symtab->cmseImportLib) {
13361336
if (impLibMaxAddr <= sym->value)
13371337
impLibMaxAddr = sym->value + sym->size;
13381338
}
1339-
if (symtab.cmseSymMap.empty())
1339+
if (ctx.symtab->cmseSymMap.empty())
13401340
return;
13411341
addMappingSymbol();
1342-
for (auto &[_, entryFunc] : symtab.cmseSymMap)
1342+
for (auto &[_, entryFunc] : ctx.symtab->cmseSymMap)
13431343
addSGVeneer(cast<Defined>(entryFunc.acleSeSym),
13441344
cast<Defined>(entryFunc.sym));
1345-
for (auto &[_, sym] : symtab.cmseImportLib) {
1346-
if (!symtab.inCMSEOutImpLib.count(sym->getName()))
1345+
for (auto &[_, sym] : ctx.symtab->cmseImportLib) {
1346+
if (!ctx.symtab->inCMSEOutImpLib.count(sym->getName()))
13471347
warn("entry function '" + sym->getName() +
13481348
"' from CMSE import library is not present in secure application");
13491349
}
13501350

1351-
if (!symtab.cmseImportLib.empty() && ctx.arg.cmseOutputLib.empty()) {
1352-
for (auto &[_, entryFunc] : symtab.cmseSymMap) {
1351+
if (!ctx.symtab->cmseImportLib.empty() && ctx.arg.cmseOutputLib.empty()) {
1352+
for (auto &[_, entryFunc] : ctx.symtab->cmseSymMap) {
13531353
Symbol *sym = entryFunc.sym;
1354-
if (!symtab.inCMSEOutImpLib.count(sym->getName()))
1354+
if (!ctx.symtab->inCMSEOutImpLib.count(sym->getName()))
13551355
warn("new entry function '" + sym->getName() +
13561356
"' introduced but no output import library specified");
13571357
}
@@ -1360,17 +1360,17 @@ ArmCmseSGSection::ArmCmseSGSection()
13601360

13611361
void ArmCmseSGSection::addSGVeneer(Symbol *acleSeSym, Symbol *sym) {
13621362
entries.emplace_back(acleSeSym, sym);
1363-
if (symtab.cmseImportLib.count(sym->getName()))
1364-
symtab.inCMSEOutImpLib[sym->getName()] = true;
1363+
if (ctx.symtab->cmseImportLib.count(sym->getName()))
1364+
ctx.symtab->inCMSEOutImpLib[sym->getName()] = true;
13651365
// Symbol addresses different, nothing to do.
13661366
if (acleSeSym->file != sym->file ||
13671367
cast<Defined>(*acleSeSym).value != cast<Defined>(*sym).value)
13681368
return;
13691369
// Only secure symbols with values equal to that of it's non-secure
13701370
// counterpart needs to be in the .gnu.sgstubs section.
13711371
ArmCmseSGVeneer *ss = nullptr;
1372-
if (symtab.cmseImportLib.count(sym->getName())) {
1373-
Defined *impSym = symtab.cmseImportLib[sym->getName()];
1372+
if (ctx.symtab->cmseImportLib.count(sym->getName())) {
1373+
Defined *impSym = ctx.symtab->cmseImportLib[sym->getName()];
13741374
ss = make<ArmCmseSGVeneer>(sym, acleSeSym, impSym->value);
13751375
} else {
13761376
ss = make<ArmCmseSGVeneer>(sym, acleSeSym);
@@ -1451,12 +1451,12 @@ template <typename ELFT> void elf::writeARMCmseImportLib() {
14511451
osIsPairs.emplace_back(make<OutputSection>(impSymTab->name, 0, 0), impSymTab);
14521452
osIsPairs.emplace_back(make<OutputSection>(shstrtab->name, 0, 0), shstrtab);
14531453

1454-
std::sort(symtab.cmseSymMap.begin(), symtab.cmseSymMap.end(),
1454+
std::sort(ctx.symtab->cmseSymMap.begin(), ctx.symtab->cmseSymMap.end(),
14551455
[](const auto &a, const auto &b) -> bool {
14561456
return a.second.sym->getVA() < b.second.sym->getVA();
14571457
});
14581458
// Copy the secure gateway entry symbols to the import library symbol table.
1459-
for (auto &p : symtab.cmseSymMap) {
1459+
for (auto &p : ctx.symtab->cmseSymMap) {
14601460
Defined *d = cast<Defined>(p.second.sym);
14611461
impSymTab->addSymbol(makeDefined(
14621462
ctx.internalFile, d->getName(), d->computeBinding(),

lld/ELF/Arch/PPC64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ void elf::writePrefixedInstruction(uint8_t *loc, uint64_t insn) {
251251

252252
static bool addOptional(StringRef name, uint64_t value,
253253
std::vector<Defined *> &defined) {
254-
Symbol *sym = symtab.find(name);
254+
Symbol *sym = ctx.symtab->find(name);
255255
if (!sym || sym->isDefined())
256256
return false;
257257
sym->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,

lld/ELF/Config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class InputSectionBase;
4444
class EhInputSection;
4545
class Defined;
4646
class Symbol;
47+
class SymbolTable;
4748
class BitcodeCompiler;
4849
class OutputSection;
4950
class LinkerScript;
@@ -600,6 +601,7 @@ struct Ctx {
600601
Defined *tlsModuleBase;
601602
};
602603
ElfSym sym;
604+
std::unique_ptr<SymbolTable> symtab;
603605

604606
SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
605607
SmallVector<ELFFileBase *, 0> objectFiles;

lld/ELF/Driver.cpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void Ctx::reset() {
109109

110110
in.reset();
111111
sym = ElfSym{};
112+
symtab = std::make_unique<SymbolTable>();
112113

113114
memoryBuffers.clear();
114115
objectFiles.clear();
@@ -155,7 +156,6 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
155156
context->e.cleanupCallback = []() {
156157
elf::ctx.reset();
157158
elf::ctx.partitions.emplace_back();
158-
symtab = SymbolTable();
159159

160160
SharedFile::vernauxNum = 0;
161161
};
@@ -167,6 +167,7 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
167167
LinkerScript script(ctx);
168168
ctx.script = &script;
169169
ctx.symAux.emplace_back();
170+
ctx.symtab = std::make_unique<SymbolTable>();
170171

171172
ctx.partitions.clear();
172173
ctx.partitions.emplace_back();
@@ -2194,7 +2195,7 @@ static void handleUndefinedGlob(Ctx &ctx, StringRef arg) {
21942195
// Calling sym->extract() in the loop is not safe because it may add new
21952196
// symbols to the symbol table, invalidating the current iterator.
21962197
SmallVector<Symbol *, 0> syms;
2197-
for (Symbol *sym : symtab.getSymbols())
2198+
for (Symbol *sym : ctx.symtab->getSymbols())
21982199
if (!sym->isPlaceholder() && pat->match(sym->getName()))
21992200
syms.push_back(sym);
22002201

@@ -2203,7 +2204,7 @@ static void handleUndefinedGlob(Ctx &ctx, StringRef arg) {
22032204
}
22042205

22052206
static void handleLibcall(Ctx &ctx, StringRef name) {
2206-
Symbol *sym = symtab.find(name);
2207+
Symbol *sym = ctx.symtab->find(name);
22072208
if (sym && sym->isLazy() && isa<BitcodeFile>(sym->file)) {
22082209
if (!ctx.arg.whyExtract.empty())
22092210
ctx.whyExtractRecords.emplace_back("<libcall>", sym->file, *sym);
@@ -2390,7 +2391,7 @@ template <class ELFT>
23902391
static void findKeepUniqueSections(Ctx &ctx, opt::InputArgList &args) {
23912392
for (auto *arg : args.filtered(OPT_keep_unique)) {
23922393
StringRef name = arg->getValue();
2393-
auto *d = dyn_cast_or_null<Defined>(symtab.find(name));
2394+
auto *d = dyn_cast_or_null<Defined>(ctx.symtab->find(name));
23942395
if (!d || !d->section) {
23952396
warn("could not find symbol " + name + " to keep unique");
23962397
continue;
@@ -2405,7 +2406,7 @@ static void findKeepUniqueSections(Ctx &ctx, opt::InputArgList &args) {
24052406

24062407
// Symbols in the dynsym could be address-significant in other executables
24072408
// or DSOs, so we conservatively mark them as address-significant.
2408-
for (Symbol *sym : symtab.getSymbols())
2409+
for (Symbol *sym : ctx.symtab->getSymbols())
24092410
if (sym->includeInDynsym())
24102411
markAddrsig(sym);
24112412

@@ -2574,24 +2575,24 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
25742575
if (!seen.insert(name).second)
25752576
continue;
25762577

2577-
Symbol *sym = symtab.find(name);
2578+
Symbol *sym = ctx.symtab->find(name);
25782579
if (!sym)
25792580
continue;
25802581

2581-
Symbol *wrap =
2582-
symtab.addUnusedUndefined(saver().save("__wrap_" + name), sym->binding);
2582+
Symbol *wrap = ctx.symtab->addUnusedUndefined(
2583+
saver().save("__wrap_" + name), sym->binding);
25832584

25842585
// If __real_ is referenced, pull in the symbol if it is lazy. Do this after
25852586
// processing __wrap_ as that may have referenced __real_.
25862587
StringRef realName = saver().save("__real_" + name);
2587-
if (Symbol *real = symtab.find(realName)) {
2588-
symtab.addUnusedUndefined(name, sym->binding);
2588+
if (Symbol *real = ctx.symtab->find(realName)) {
2589+
ctx.symtab->addUnusedUndefined(name, sym->binding);
25892590
// Update sym's binding, which will replace real's later in
25902591
// SymbolTable::wrap.
25912592
sym->binding = real->binding;
25922593
}
25932594

2594-
Symbol *real = symtab.addUnusedUndefined(realName);
2595+
Symbol *real = ctx.symtab->addUnusedUndefined(realName);
25952596
v.push_back({sym, real, wrap});
25962597

25972598
// We want to tell LTO not to inline symbols to be overwritten
@@ -2626,7 +2627,7 @@ static void combineVersionedSymbol(Symbol &sym,
26262627
//
26272628
// * There is a definition of foo@v1 and foo@@v1.
26282629
// * There is a definition of foo@v1 and foo.
2629-
Defined *sym2 = dyn_cast_or_null<Defined>(symtab.find(sym.getName()));
2630+
Defined *sym2 = dyn_cast_or_null<Defined>(ctx.symtab->find(sym.getName()));
26302631
if (!sym2)
26312632
return;
26322633
const char *suffix2 = sym2->getVersionSuffix();
@@ -2681,7 +2682,7 @@ static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
26812682
// symbols with a non-default version (foo@v1) and check whether it should be
26822683
// combined with foo or foo@@v1.
26832684
if (ctx.arg.versionDefinitions.size() > 2)
2684-
for (Symbol *sym : symtab.getSymbols())
2685+
for (Symbol *sym : ctx.symtab->getSymbols())
26852686
if (sym->hasVersionSuffix)
26862687
combineVersionedSymbol(*sym, map);
26872688

@@ -2697,7 +2698,7 @@ static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
26972698

26982699
// Update pointers in the symbol table.
26992700
for (const WrappedSymbol &w : wrapped)
2700-
symtab.wrap(w.sym, w.real, w.wrap);
2701+
ctx.symtab->wrap(w.sym, w.real, w.wrap);
27012702
}
27022703

27032704
static void reportMissingFeature(StringRef config, const Twine &report) {
@@ -2861,22 +2862,22 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
28612862

28622863
// Handle --trace-symbol.
28632864
for (auto *arg : args.filtered(OPT_trace_symbol))
2864-
symtab.insert(arg->getValue())->traced = true;
2865+
ctx.symtab->insert(arg->getValue())->traced = true;
28652866

28662867
ctx.internalFile = createInternalFile("<internal>");
28672868

28682869
// Handle -u/--undefined before input files. If both a.a and b.so define foo,
28692870
// -u foo a.a b.so will extract a.a.
28702871
for (StringRef name : ctx.arg.undefined)
2871-
symtab.addUnusedUndefined(name)->referenced = true;
2872+
ctx.symtab->addUnusedUndefined(name)->referenced = true;
28722873

28732874
parseFiles(files, armCmseImpLib);
28742875

28752876
// Create dynamic sections for dynamic linking and static PIE.
28762877
ctx.arg.hasDynSymTab = !ctx.sharedFiles.empty() || ctx.arg.isPic;
28772878

28782879
// If an entry symbol is in a static archive, pull out that file now.
2879-
if (Symbol *sym = symtab.find(ctx.arg.entry))
2880+
if (Symbol *sym = ctx.symtab->find(ctx.arg.entry))
28802881
handleUndefined(ctx, sym, "--entry");
28812882

28822883
// Handle the `--undefined-glob <pattern>` options.
@@ -2890,13 +2891,13 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
28902891

28912892
// Prevent LTO from removing any definition referenced by -u.
28922893
for (StringRef name : ctx.arg.undefined)
2893-
if (Defined *sym = dyn_cast_or_null<Defined>(symtab.find(name)))
2894+
if (Defined *sym = dyn_cast_or_null<Defined>(ctx.symtab->find(name)))
28942895
sym->isUsedInRegularObj = true;
28952896

28962897
// Mark -init and -fini symbols so that the LTO doesn't eliminate them.
2897-
if (Symbol *sym = dyn_cast_or_null<Defined>(symtab.find(ctx.arg.init)))
2898+
if (Symbol *sym = dyn_cast_or_null<Defined>(ctx.symtab->find(ctx.arg.init)))
28982899
sym->isUsedInRegularObj = true;
2899-
if (Symbol *sym = dyn_cast_or_null<Defined>(symtab.find(ctx.arg.fini)))
2900+
if (Symbol *sym = dyn_cast_or_null<Defined>(ctx.symtab->find(ctx.arg.fini)))
29002901
sym->isUsedInRegularObj = true;
29012902

29022903
// If any of our inputs are bitcode files, the LTO code generator may create
@@ -2977,7 +2978,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
29772978
// name "foo@ver1") rather do harm, so we don't call this if -r is given.
29782979
if (!ctx.arg.relocatable) {
29792980
llvm::TimeTraceScope timeScope("Process symbol versions");
2980-
symtab.scanVersionScript();
2981+
ctx.symtab->scanVersionScript();
29812982
}
29822983

29832984
// Skip the normal linked output if some LTO options are specified.

lld/ELF/ICF.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ template <class ELFT> void ICF<ELFT>::run() {
468468
// cannot be merged with the later computeIsPreemptible() pass which is used
469469
// by scanRelocations().
470470
if (ctx.arg.hasDynSymTab)
471-
for (Symbol *sym : symtab.getSymbols())
471+
for (Symbol *sym : ctx.symtab->getSymbols())
472472
sym->isPreemptible = computeIsPreemptible(*sym);
473473

474474
// Two text sections may have identical content and relocations but different
@@ -568,7 +568,7 @@ template <class ELFT> void ICF<ELFT>::run() {
568568
d->folded = true;
569569
}
570570
};
571-
for (Symbol *sym : symtab.getSymbols())
571+
for (Symbol *sym : ctx.symtab->getSymbols())
572572
fold(sym);
573573
parallelForEach(ctx.objectFiles, [&](ELFFileBase *file) {
574574
for (Symbol *sym : file->getLocalSymbols())

0 commit comments

Comments
 (0)