Skip to content

Commit d6fa74a

Browse files
committed
[ELF] Merge exportDynamic/isExported and remove Symbol::includeInDynsym
Commit 3733ed6 introduced isExported to cache includeInDynsym. If we don't unnecessarily set isExported for undefined symbols, exportDynamic/includeInDynsym can be replaced with isExported.
1 parent 3b2f4f4 commit d6fa74a

File tree

7 files changed

+34
-40
lines changed

7 files changed

+34
-40
lines changed

lld/ELF/Driver.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2554,7 +2554,8 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
25542554
for (Symbol *sym : obj->getGlobalSymbols()) {
25552555
if (!sym->isDefined())
25562556
continue;
2557-
if (ctx.hasDynsym && sym->includeInDynsym(ctx))
2557+
if (ctx.hasDynsym && ctx.arg.exportDynamic &&
2558+
sym->computeBinding(ctx) != STB_LOCAL)
25582559
sym->isExported = true;
25592560
if (sym->hasVersionSuffix)
25602561
sym->parseSymbolVersion(ctx);

lld/ELF/InputFiles.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,7 @@ template <class ELFT> void SharedFile::parse() {
15741574
}
15751575
Symbol *s = ctx.symtab->addSymbol(
15761576
Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()});
1577-
s->exportDynamic = true;
1577+
s->isExported = true;
15781578
if (sym.getBinding() != STB_WEAK &&
15791579
ctx.arg.unresolvedSymbolsInShlib != UnresolvedPolicy::Ignore)
15801580
requiredSymbols.push_back(s);
@@ -1771,7 +1771,7 @@ static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
17711771
nullptr);
17721772
// The definition can be omitted if all bitcode definitions satisfy
17731773
// `canBeOmittedFromSymbolTable()` and isUsedInRegularObj is false.
1774-
// The latter condition is tested in Symbol::includeInDynsym.
1774+
// The latter condition is tested in parseVersionAndComputeIsPreemptible.
17751775
sym->ltoCanOmit = objSym.canBeOmittedFromSymbolTable() &&
17761776
(!sym->isDefined() || sym->ltoCanOmit);
17771777
sym->resolve(ctx, newSym);

lld/ELF/SymbolTable.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void SymbolTable::handleDynamicList() {
203203
syms = findByVersion(ver);
204204

205205
for (Symbol *sym : syms)
206-
sym->exportDynamic = sym->inDynamicList = true;
206+
sym->isExported = sym->inDynamicList = true;
207207
}
208208
}
209209

@@ -350,10 +350,8 @@ void SymbolTable::scanVersionScript() {
350350
assignAsterisk(pat, &v, true);
351351
}
352352

353-
// isPreemptible is false at this point. To correctly compute the binding of a
354-
// Defined (which is used by includeInDynsym(ctx)), we need to know if it is
355-
// VER_NDX_LOCAL or not. Compute symbol versions before handling
356-
// --dynamic-list.
353+
// Handle --dynamic-list. If a specified symbol is also matched by local: in a
354+
// version script, the version script takes precedence.
357355
handleDynamicList();
358356
}
359357

lld/ELF/Symbols.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -268,16 +268,6 @@ uint8_t Symbol::computeBinding(Ctx &ctx) const {
268268
return binding;
269269
}
270270

271-
bool Symbol::includeInDynsym(Ctx &ctx) const {
272-
if (computeBinding(ctx) == STB_LOCAL)
273-
return false;
274-
if (!isDefined() && !isCommon())
275-
return true;
276-
277-
return exportDynamic ||
278-
(ctx.arg.exportDynamic && (isUsedInRegularObj || !ltoCanOmit));
279-
}
280-
281271
// Print out a log message for --trace-symbol.
282272
void elf::printTraceSymbol(const Symbol &sym, StringRef name) {
283273
std::string s;
@@ -374,9 +364,18 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
374364
for (Symbol *sym : ctx.symtab->getSymbols()) {
375365
if (sym->hasVersionSuffix)
376366
sym->parseSymbolVersion(ctx);
377-
if (hasDynsym) {
378-
sym->isExported = sym->includeInDynsym(ctx);
379-
sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
367+
if (!hasDynsym)
368+
continue;
369+
if (sym->computeBinding(ctx) == STB_LOCAL) {
370+
sym->isExported = false;
371+
continue;
372+
}
373+
if (!sym->isDefined() && !sym->isCommon()) {
374+
sym->isPreemptible = computeIsPreemptible(ctx, *sym);
375+
} else if (ctx.arg.exportDynamic &&
376+
(sym->isUsedInRegularObj || !sym->ltoCanOmit)) {
377+
sym->isExported = true;
378+
sym->isPreemptible = computeIsPreemptible(ctx, *sym);
380379
}
381380
}
382381
}
@@ -655,7 +654,7 @@ void Symbol::resolve(Ctx &ctx, const LazySymbol &other) {
655654
}
656655

657656
void Symbol::resolve(Ctx &ctx, const SharedSymbol &other) {
658-
exportDynamic = true;
657+
isExported = true;
659658
if (isPlaceholder()) {
660659
other.overwrite(*this);
661660
return;

lld/ELF/Symbols.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ class Symbol {
105105
uint8_t partition;
106106

107107
// True if this symbol is preemptible at load time.
108+
//
109+
// Primarily set in two locations, (a) parseVersionAndComputeIsPreemptible and
110+
// (b) demoteSymbolsAndComputeIsPreemptible.
108111
LLVM_PREFERRED_TYPE(bool)
109112
uint8_t isPreemptible : 1;
110113

@@ -131,16 +134,9 @@ class Symbol {
131134
// - If -shared or --export-dynamic is specified, any symbol in an object
132135
// file/bitcode sets this property, unless suppressed by LTO
133136
// canBeOmittedFromSymbolTable().
134-
//
135-
// Primarily set in two locations, (a) after parseSymbolVersion and
136-
// (b) during demoteSymbols.
137137
LLVM_PREFERRED_TYPE(bool)
138138
uint8_t isExported : 1;
139139

140-
// Used to compute isExported. Set when defined or referenced by a SharedFile.
141-
LLVM_PREFERRED_TYPE(bool)
142-
uint8_t exportDynamic : 1;
143-
144140
LLVM_PREFERRED_TYPE(bool)
145141
uint8_t ltoCanOmit : 1;
146142

@@ -159,7 +155,6 @@ class Symbol {
159155
stOther = (stOther & ~3) | visibility;
160156
}
161157

162-
bool includeInDynsym(Ctx &) const;
163158
uint8_t computeBinding(Ctx &) const;
164159
bool isGlobal() const { return binding == llvm::ELF::STB_GLOBAL; }
165160
bool isWeak() const { return binding == llvm::ELF::STB_WEAK; }
@@ -247,8 +242,8 @@ class Symbol {
247242
Symbol(Kind k, InputFile *file, StringRef name, uint8_t binding,
248243
uint8_t stOther, uint8_t type)
249244
: file(file), nameData(name.data()), nameSize(name.size()), type(type),
250-
binding(binding), stOther(stOther), symbolKind(k), exportDynamic(false),
251-
ltoCanOmit(false), archSpecificBit(false) {}
245+
binding(binding), stOther(stOther), symbolKind(k), ltoCanOmit(false),
246+
archSpecificBit(false) {}
252247

253248
void overwrite(Symbol &sym, Kind k) const {
254249
if (sym.traced)

lld/ELF/SyntheticSections.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4776,8 +4776,8 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
47764776
add(*part.buildId);
47774777
}
47784778

4779-
// dynSymTab is always present to simplify sym->includeInDynsym(ctx) in
4780-
// finalizeSections.
4779+
// dynSymTab is always present to simplify several finalizeSections
4780+
// functions.
47814781
part.dynStrTab = std::make_unique<StringTableSection>(ctx, ".dynstr", true);
47824782
part.dynSymTab =
47834783
std::make_unique<SymbolTableSection<ELFT>>(ctx, *part.dynStrTab);

lld/ELF/Writer.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,12 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
296296
sym->type)
297297
.overwrite(*sym);
298298
sym->versionId = VER_NDX_GLOBAL;
299-
if (hasDynsym && sym->includeInDynsym(ctx))
300-
sym->isExported = true;
301299
}
302300
}
303301

304302
if (hasDynsym)
305-
sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
303+
sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
304+
computeIsPreemptible(ctx, *sym);
306305
}
307306
}
308307

@@ -1841,9 +1840,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
18411840

18421841
// If the previous code block defines any non-hidden symbols (e.g.
18431842
// __global_pointer$), they may be exported.
1844-
if (ctx.hasDynsym)
1843+
if (ctx.hasDynsym && ctx.arg.exportDynamic)
18451844
for (Symbol *sym : ctx.synthesizedSymbols)
1846-
sym->isExported = sym->includeInDynsym(ctx);
1845+
if (sym->computeBinding(ctx) != STB_LOCAL)
1846+
sym->isExported = true;
18471847

18481848
demoteSymbolsAndComputeIsPreemptible(ctx);
18491849

@@ -1931,7 +1931,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
19311931

19321932
// computeBinding might localize a linker-synthesized hidden symbol
19331933
// (e.g. __global_pointer$) that was considered exported.
1934-
if (sym->isExported && !sym->isLocal()) {
1934+
if (ctx.hasDynsym && (sym->isUndefined() || sym->isExported) &&
1935+
!sym->isLocal()) {
19351936
ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
19361937
if (auto *file = dyn_cast<SharedFile>(sym->file))
19371938
if (file->isNeeded && !sym->isUndefined())

0 commit comments

Comments
 (0)