Skip to content

Commit c650880

Browse files
committed
[ELF] Simplify handling of exportDynamic and canBeOmittedFromSymbolTable
When computing whether a defined symbol is exported, we set `exportDynamic` in Defined and CommonSymbol's ctor and merge the bit in symbol resolution. The complexity is for the LTO special case canBeOmittedFromSymbolTable, which can be simplified by introducing a new bit. We might simplify the state by caching includeInDynsym in exportDynamic in the future.
1 parent aedc81b commit c650880

File tree

4 files changed

+15
-19
lines changed

4 files changed

+15
-19
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,8 +1742,11 @@ static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
17421742
} else {
17431743
Defined newSym(ctx, &f, StringRef(), binding, visibility, type, 0, 0,
17441744
nullptr);
1745-
if (objSym.canBeOmittedFromSymbolTable())
1746-
newSym.exportDynamic = false;
1745+
// The definition can be omitted if all bitcode definitions satisfy
1746+
// `canBeOmittedFromSymbolTable()` and isUsedInRegularObj is false.
1747+
// The latter condition is tested in Symbol::includeInDynsym.
1748+
sym->ltoCanOmit = objSym.canBeOmittedFromSymbolTable() &&
1749+
(!sym->isDefined() || sym->ltoCanOmit);
17471750
sym->resolve(ctx, newSym);
17481751
}
17491752
}

lld/ELF/Relocations.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ static void replaceWithDefined(Ctx &ctx, Symbol &sym, SectionBase &sec,
310310
.overwrite(sym);
311311

312312
sym.versionId = old.versionId;
313-
sym.exportDynamic = true;
314313
sym.isUsedInRegularObj = true;
315314
// A copy relocated alias may need a GOT entry.
316315
sym.flags.store(old.flags.load(std::memory_order_relaxed) & NEEDS_GOT,

lld/ELF/Symbols.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ bool Symbol::includeInDynsym(Ctx &ctx) const {
278278
// __pthread_initialize_minimal reference in csu/libc-start.c.
279279
return !(isUndefWeak() && ctx.arg.noDynamicLinker);
280280

281-
return exportDynamic;
281+
return exportDynamic ||
282+
(ctx.arg.exportDynamic && (isUsedInRegularObj || !ltoCanOmit));
282283
}
283284

284285
// Print out a log message for --trace-symbol.
@@ -375,9 +376,6 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
375376
// and that's the result of symbol resolution. However, symbols that
376377
// were not chosen still affect some symbol properties.
377378
void Symbol::mergeProperties(const Symbol &other) {
378-
if (other.exportDynamic)
379-
exportDynamic = true;
380-
381379
// DSO symbols do not affect visibility in the output.
382380
if (!other.isShared() && other.visibility() != STV_DEFAULT) {
383381
uint8_t v = visibility(), ov = other.visibility();
@@ -564,8 +562,6 @@ void Symbol::checkDuplicate(Ctx &ctx, const Defined &other) const {
564562
}
565563

566564
void Symbol::resolve(Ctx &ctx, const CommonSymbol &other) {
567-
if (other.exportDynamic)
568-
exportDynamic = true;
569565
if (other.visibility() != STV_DEFAULT) {
570566
uint8_t v = visibility(), ov = other.visibility();
571567
setVisibility(v == STV_DEFAULT ? ov : std::min(v, ov));
@@ -602,8 +598,6 @@ void Symbol::resolve(Ctx &ctx, const CommonSymbol &other) {
602598
}
603599

604600
void Symbol::resolve(Ctx &ctx, const Defined &other) {
605-
if (other.exportDynamic)
606-
exportDynamic = true;
607601
if (other.visibility() != STV_DEFAULT) {
608602
uint8_t v = visibility(), ov = other.visibility();
609603
setVisibility(v == STV_DEFAULT ? ov : std::min(v, ov));

lld/ELF/Symbols.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,8 @@ class Symbol {
130130
LLVM_PREFERRED_TYPE(bool)
131131
uint8_t exportDynamic : 1;
132132

133-
// True if the symbol is in the --dynamic-list file. A Defined symbol with
134-
// protected or default visibility with this property is required to be
135-
// exported into .dynsym.
136133
LLVM_PREFERRED_TYPE(bool)
137-
uint8_t inDynamicList : 1;
134+
uint8_t ltoCanOmit : 1;
138135

139136
// Used to track if there has been at least one undefined reference to the
140137
// symbol. For Undefined and SharedSymbol, the binding may change to STB_WEAK
@@ -252,7 +249,7 @@ class Symbol {
252249
uint8_t stOther, uint8_t type)
253250
: file(file), nameData(name.data()), nameSize(name.size()), type(type),
254251
binding(binding), stOther(stOther), symbolKind(k), exportDynamic(false),
255-
archSpecificBit(false) {}
252+
ltoCanOmit(false), archSpecificBit(false) {}
256253

257254
void overwrite(Symbol &sym, Kind k) const {
258255
if (sym.traced)
@@ -330,6 +327,12 @@ class Symbol {
330327
LLVM_PREFERRED_TYPE(bool)
331328
uint8_t thunkAccessed : 1;
332329

330+
// True if the symbol is in the --dynamic-list file. A Defined symbol with
331+
// protected or default visibility with this property is required to be
332+
// exported into .dynsym.
333+
LLVM_PREFERRED_TYPE(bool)
334+
uint8_t inDynamicList : 1;
335+
333336
void setFlags(uint16_t bits) {
334337
flags.fetch_or(bits, std::memory_order_relaxed);
335338
}
@@ -365,7 +368,6 @@ class Defined : public Symbol {
365368
SectionBase *section)
366369
: Symbol(DefinedKind, file, name, binding, stOther, type), value(value),
367370
size(size), section(section) {
368-
exportDynamic = ctx.arg.exportDynamic;
369371
}
370372
void overwrite(Symbol &sym) const;
371373

@@ -403,7 +405,6 @@ class CommonSymbol : public Symbol {
403405
uint8_t stOther, uint8_t type, uint64_t alignment, uint64_t size)
404406
: Symbol(CommonKind, file, name, binding, stOther, type),
405407
alignment(alignment), size(size) {
406-
exportDynamic = ctx.arg.exportDynamic;
407408
}
408409
void overwrite(Symbol &sym) const {
409410
Symbol::overwrite(sym, CommonKind);
@@ -447,7 +448,6 @@ class SharedSymbol : public Symbol {
447448
uint32_t alignment)
448449
: Symbol(SharedKind, &file, name, binding, stOther, type), value(value),
449450
size(size), alignment(alignment) {
450-
exportDynamic = true;
451451
dsoProtected = visibility() == llvm::ELF::STV_PROTECTED;
452452
// GNU ifunc is a mechanism to allow user-supplied functions to
453453
// resolve PLT slot values at load-time. This is contrary to the

0 commit comments

Comments
 (0)