[lld] d6fa74a - [ELF] Merge exportDynamic/isExported and remove Symbol::includeInDynsym
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 30 22:26:30 PST 2025
Author: Fangrui Song
Date: 2025-01-30T22:24:04-08:00
New Revision: d6fa74ab3d4cc77005836e72a2d6fe222bab4c59
URL: https://github.com/llvm/llvm-project/commit/d6fa74ab3d4cc77005836e72a2d6fe222bab4c59
DIFF: https://github.com/llvm/llvm-project/commit/d6fa74ab3d4cc77005836e72a2d6fe222bab4c59.diff
LOG: [ELF] Merge exportDynamic/isExported and remove Symbol::includeInDynsym
Commit 3733ed6f1c6b0eef1e13e175ac81ad309fc0b080 introduced isExported to
cache includeInDynsym. If we don't unnecessarily set isExported for
undefined symbols, exportDynamic/includeInDynsym can be replaced with
isExported.
Added:
Modified:
lld/ELF/Driver.cpp
lld/ELF/InputFiles.cpp
lld/ELF/SymbolTable.cpp
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/ELF/SyntheticSections.cpp
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 98523429a5078c..acbc97b331b0e1 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2554,7 +2554,8 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
for (Symbol *sym : obj->getGlobalSymbols()) {
if (!sym->isDefined())
continue;
- if (ctx.hasDynsym && sym->includeInDynsym(ctx))
+ if (ctx.hasDynsym && ctx.arg.exportDynamic &&
+ sym->computeBinding(ctx) != STB_LOCAL)
sym->isExported = true;
if (sym->hasVersionSuffix)
sym->parseSymbolVersion(ctx);
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 42d0e4c202ec61..16943c484d96bc 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1574,7 +1574,7 @@ template <class ELFT> void SharedFile::parse() {
}
Symbol *s = ctx.symtab->addSymbol(
Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()});
- s->exportDynamic = true;
+ s->isExported = true;
if (sym.getBinding() != STB_WEAK &&
ctx.arg.unresolvedSymbolsInShlib != UnresolvedPolicy::Ignore)
requiredSymbols.push_back(s);
@@ -1771,7 +1771,7 @@ static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
nullptr);
// The definition can be omitted if all bitcode definitions satisfy
// `canBeOmittedFromSymbolTable()` and isUsedInRegularObj is false.
- // The latter condition is tested in Symbol::includeInDynsym.
+ // The latter condition is tested in parseVersionAndComputeIsPreemptible.
sym->ltoCanOmit = objSym.canBeOmittedFromSymbolTable() &&
(!sym->isDefined() || sym->ltoCanOmit);
sym->resolve(ctx, newSym);
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 975700505facb4..b8a70d4e898fc2 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -203,7 +203,7 @@ void SymbolTable::handleDynamicList() {
syms = findByVersion(ver);
for (Symbol *sym : syms)
- sym->exportDynamic = sym->inDynamicList = true;
+ sym->isExported = sym->inDynamicList = true;
}
}
@@ -350,10 +350,8 @@ void SymbolTable::scanVersionScript() {
assignAsterisk(pat, &v, true);
}
- // isPreemptible is false at this point. To correctly compute the binding of a
- // Defined (which is used by includeInDynsym(ctx)), we need to know if it is
- // VER_NDX_LOCAL or not. Compute symbol versions before handling
- // --dynamic-list.
+ // Handle --dynamic-list. If a specified symbol is also matched by local: in a
+ // version script, the version script takes precedence.
handleDynamicList();
}
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index b10391c65dfdc3..890877cb1bc046 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -268,16 +268,6 @@ uint8_t Symbol::computeBinding(Ctx &ctx) const {
return binding;
}
-bool Symbol::includeInDynsym(Ctx &ctx) const {
- if (computeBinding(ctx) == STB_LOCAL)
- return false;
- if (!isDefined() && !isCommon())
- return true;
-
- return exportDynamic ||
- (ctx.arg.exportDynamic && (isUsedInRegularObj || !ltoCanOmit));
-}
-
// Print out a log message for --trace-symbol.
void elf::printTraceSymbol(const Symbol &sym, StringRef name) {
std::string s;
@@ -374,9 +364,18 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (sym->hasVersionSuffix)
sym->parseSymbolVersion(ctx);
- if (hasDynsym) {
- sym->isExported = sym->includeInDynsym(ctx);
- sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
+ if (!hasDynsym)
+ continue;
+ if (sym->computeBinding(ctx) == STB_LOCAL) {
+ sym->isExported = false;
+ continue;
+ }
+ if (!sym->isDefined() && !sym->isCommon()) {
+ sym->isPreemptible = computeIsPreemptible(ctx, *sym);
+ } else if (ctx.arg.exportDynamic &&
+ (sym->isUsedInRegularObj || !sym->ltoCanOmit)) {
+ sym->isExported = true;
+ sym->isPreemptible = computeIsPreemptible(ctx, *sym);
}
}
}
@@ -655,7 +654,7 @@ void Symbol::resolve(Ctx &ctx, const LazySymbol &other) {
}
void Symbol::resolve(Ctx &ctx, const SharedSymbol &other) {
- exportDynamic = true;
+ isExported = true;
if (isPlaceholder()) {
other.overwrite(*this);
return;
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 48df6f60db864b..64f2f6eaa8d09d 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -105,6 +105,9 @@ class Symbol {
uint8_t partition;
// True if this symbol is preemptible at load time.
+ //
+ // Primarily set in two locations, (a) parseVersionAndComputeIsPreemptible and
+ // (b) demoteSymbolsAndComputeIsPreemptible.
LLVM_PREFERRED_TYPE(bool)
uint8_t isPreemptible : 1;
@@ -131,16 +134,9 @@ class Symbol {
// - If -shared or --export-dynamic is specified, any symbol in an object
// file/bitcode sets this property, unless suppressed by LTO
// canBeOmittedFromSymbolTable().
- //
- // Primarily set in two locations, (a) after parseSymbolVersion and
- // (b) during demoteSymbols.
LLVM_PREFERRED_TYPE(bool)
uint8_t isExported : 1;
- // Used to compute isExported. Set when defined or referenced by a SharedFile.
- LLVM_PREFERRED_TYPE(bool)
- uint8_t exportDynamic : 1;
-
LLVM_PREFERRED_TYPE(bool)
uint8_t ltoCanOmit : 1;
@@ -159,7 +155,6 @@ class Symbol {
stOther = (stOther & ~3) | visibility;
}
- bool includeInDynsym(Ctx &) const;
uint8_t computeBinding(Ctx &) const;
bool isGlobal() const { return binding == llvm::ELF::STB_GLOBAL; }
bool isWeak() const { return binding == llvm::ELF::STB_WEAK; }
@@ -247,8 +242,8 @@ class Symbol {
Symbol(Kind k, InputFile *file, StringRef name, uint8_t binding,
uint8_t stOther, uint8_t type)
: file(file), nameData(name.data()), nameSize(name.size()), type(type),
- binding(binding), stOther(stOther), symbolKind(k), exportDynamic(false),
- ltoCanOmit(false), archSpecificBit(false) {}
+ binding(binding), stOther(stOther), symbolKind(k), ltoCanOmit(false),
+ archSpecificBit(false) {}
void overwrite(Symbol &sym, Kind k) const {
if (sym.traced)
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index eb07d82fc96012..ffa6e3c008c48e 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -4776,8 +4776,8 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
add(*part.buildId);
}
- // dynSymTab is always present to simplify sym->includeInDynsym(ctx) in
- // finalizeSections.
+ // dynSymTab is always present to simplify several finalizeSections
+ // functions.
part.dynStrTab = std::make_unique<StringTableSection>(ctx, ".dynstr", true);
part.dynSymTab =
std::make_unique<SymbolTableSection<ELFT>>(ctx, *part.dynStrTab);
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 6c7bcee02047b5..3ba1cdbce572b7 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -296,13 +296,12 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
sym->type)
.overwrite(*sym);
sym->versionId = VER_NDX_GLOBAL;
- if (hasDynsym && sym->includeInDynsym(ctx))
- sym->isExported = true;
}
}
if (hasDynsym)
- sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
+ sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
+ computeIsPreemptible(ctx, *sym);
}
}
@@ -1841,9 +1840,10 @@ 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.
- if (ctx.hasDynsym)
+ if (ctx.hasDynsym && ctx.arg.exportDynamic)
for (Symbol *sym : ctx.synthesizedSymbols)
- sym->isExported = sym->includeInDynsym(ctx);
+ if (sym->computeBinding(ctx) != STB_LOCAL)
+ sym->isExported = true;
demoteSymbolsAndComputeIsPreemptible(ctx);
@@ -1931,7 +1931,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// computeBinding might localize a linker-synthesized hidden symbol
// (e.g. __global_pointer$) that was considered exported.
- if (sym->isExported && !sym->isLocal()) {
+ if (ctx.hasDynsym && (sym->isUndefined() || sym->isExported) &&
+ !sym->isLocal()) {
ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
if (auto *file = dyn_cast<SharedFile>(sym->file))
if (file->isNeeded && !sym->isUndefined())
More information about the llvm-commits
mailing list