aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2025-01-26 20:43:03 -0800
committerFangrui Song <i@maskray.me>2025-01-26 20:43:03 -0800
commit1a4d6de1b532149b10522eae5dabce39e5f7c687 (patch)
tree9801d66a6642f4ae18f6c0582878b759781f9eab
parent2a26292388fcab0c857c91b2d08074c33abd37e8 (diff)
downloadllvm-1a4d6de1b532149b10522eae5dabce39e5f7c687.zip
llvm-1a4d6de1b532149b10522eae5dabce39e5f7c687.tar.gz
llvm-1a4d6de1b532149b10522eae5dabce39e5f7c687.tar.bz2
[ELF] Remove redundant isExported computation
Commit 2a26292388fcab0c857c91b2d08074c33abd37e8 made `isExported` accurate except a few linker-synthesized symbols in finalizeSections. We can collect these linker-synthesized symbols into a vector and avoid recomputation for other symbols.
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Writer.cpp12
2 files changed, 11 insertions, 2 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index b285948..b1d7fb8 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -619,6 +619,7 @@ struct Ctx : CommonLinkerContext {
};
ElfSym sym{};
std::unique_ptr<SymbolTable> symtab;
+ SmallVector<Symbol *, 0> synthesizedSymbols;
SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
SmallVector<ELFFileBase *, 0> objectFiles;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index b7c4790..4b75137 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -149,6 +149,7 @@ static Defined *addOptionalRegular(Ctx &ctx, StringRef name, SectionBase *sec,
if (!s || s->isDefined() || s->isCommon())
return nullptr;
+ ctx.synthesizedSymbols.push_back(s);
s->resolve(ctx, Defined{ctx, ctx.internalFile, StringRef(), STB_GLOBAL,
stOther, STT_NOTYPE, val,
/*size=*/0, sec});
@@ -282,6 +283,7 @@ static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
llvm::TimeTraceScope timeScope("Demote symbols");
DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
+ bool hasDynSymTab = ctx.arg.hasDynSymTab;
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (auto *d = dyn_cast<Defined>(sym)) {
if (d->section && !d->section->isLive())
@@ -294,11 +296,12 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
sym->type)
.overwrite(*sym);
sym->versionId = VER_NDX_GLOBAL;
+ if (sym->includeInDynsym(ctx))
+ sym->isExported = true;
}
}
- sym->isExported = sym->includeInDynsym(ctx);
- if (ctx.arg.hasDynSymTab)
+ if (hasDynSymTab)
sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
}
}
@@ -1846,6 +1849,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
}
}
+ // If the previous code block defines any non-hidden symbols (e.g.
+ // __global_pointer$), they may be exported.
+ for (Symbol *sym : ctx.synthesizedSymbols)
+ sym->isExported = sym->includeInDynsym(ctx);
+
demoteSymbolsAndComputeIsPreemptible(ctx);
if (ctx.arg.copyRelocs && ctx.arg.discard != DiscardPolicy::None)