Skip to content

Commit 3733ed6

Browse files
committed
[ELF] Introduce Symbol::isExported to cache includeInDynsym
isExported, intended to replace exportDynamic, is primarily set in two locations, (a) after parseSymbolVersion and (b) during demoteSymbols. In the future, we should try removing exportDynamic. Currently, merging exportDynamic/isExported would cause riscv-gp.s to fail: * The first isExported computation considers the undefined symbol exported * Defined as a linker-synthesized symbol * isExported remains true, while it should be false
1 parent 6b93a1f commit 3733ed6

File tree

7 files changed

+32
-25
lines changed

7 files changed

+32
-25
lines changed

lld/ELF/Driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2452,7 +2452,7 @@ static void readSymbolPartitionSection(Ctx &ctx, InputSectionBase *s) {
24522452
sym = readEntry(s->file, rels.rels);
24532453
else
24542454
sym = readEntry(s->file, rels.relas);
2455-
if (!isa_and_nonnull<Defined>(sym) || !sym->includeInDynsym(ctx))
2455+
if (!isa_and_nonnull<Defined>(sym) || !sym->isExported)
24562456
return;
24572457

24582458
StringRef partName = reinterpret_cast<const char *>(s->content().data());

lld/ELF/LTO.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,12 @@ void BitcodeCompiler::add(BitcodeFile &f) {
250250
// 5) Symbols that will be referenced after linker wrapping is performed.
251251
r.VisibleToRegularObj = ctx.arg.relocatable || sym->isUsedInRegularObj ||
252252
sym->referencedAfterWrap ||
253-
(r.Prevailing && sym->includeInDynsym(ctx)) ||
253+
(r.Prevailing && sym->isExported) ||
254254
usedStartStop.count(objSym.getSectionName());
255255
// Identify symbols exported dynamically, and that therefore could be
256256
// referenced by a shared library not visible to the linker.
257257
r.ExportDynamic = sym->computeBinding(ctx) != STB_LOCAL &&
258-
(ctx.arg.exportDynamic || sym->exportDynamic);
258+
(ctx.arg.exportDynamic || sym->isExported);
259259
const auto *dr = dyn_cast<Defined>(sym);
260260
r.FinalDefinitionInLinkageUnit =
261261
(isExec || sym->visibility() != STV_DEFAULT) && dr &&

lld/ELF/MarkLive.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
221221
// Preserve externally-visible symbols if the symbols defined by this
222222
// file can interpose other ELF file's symbols at runtime.
223223
for (Symbol *sym : ctx.symtab->getSymbols())
224-
if (sym->includeInDynsym(ctx) && sym->partition == partition)
224+
if (sym->isExported && sym->partition == partition)
225225
markSymbol(sym);
226226

227227
// If this isn't the main partition, that's all that we need to preserve.

lld/ELF/Relocations.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
10561056
// direct relocation on through.
10571057
if (LLVM_UNLIKELY(isIfunc) && ctx.arg.zIfuncNoplt) {
10581058
std::lock_guard<std::mutex> lock(ctx.relocMutex);
1059-
sym.exportDynamic = true;
1059+
sym.isExported = true;
10601060
ctx.mainPart->relaDyn->addSymbolReloc(type, *sec, offset, sym, addend,
10611061
type);
10621062
return;

lld/ELF/Symbols.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,9 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
379379
for (Symbol *sym : ctx.symtab->getSymbols()) {
380380
if (sym->hasVersionSuffix)
381381
sym->parseSymbolVersion(ctx);
382+
sym->isExported = sym->includeInDynsym(ctx);
382383
if (hasDynSymTab)
383-
sym->isPreemptible =
384-
sym->includeInDynsym(ctx) && computeIsPreemptible(ctx, *sym);
384+
sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
385385
}
386386
}
387387

lld/ELF/Symbols.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,23 +127,18 @@ class Symbol {
127127
// - If -shared or --export-dynamic is specified, any symbol in an object
128128
// file/bitcode sets this property, unless suppressed by LTO
129129
// canBeOmittedFromSymbolTable().
130+
//
131+
// Primarily set in two locations, (a) after parseSymbolVersion and
132+
// (b) during demoteSymbols.
130133
LLVM_PREFERRED_TYPE(bool)
131-
uint8_t exportDynamic : 1;
134+
uint8_t isExported : 1;
132135

136+
// Used to compute isExported. Set when defined or referenced by a SharedFile.
133137
LLVM_PREFERRED_TYPE(bool)
134-
uint8_t ltoCanOmit : 1;
135-
136-
// Used to track if there has been at least one undefined reference to the
137-
// symbol. For Undefined and SharedSymbol, the binding may change to STB_WEAK
138-
// if the first undefined reference from a non-shared object is weak.
139-
LLVM_PREFERRED_TYPE(bool)
140-
uint8_t referenced : 1;
138+
uint8_t exportDynamic : 1;
141139

142-
// Used to track if this symbol will be referenced after wrapping is performed
143-
// (i.e. this will be true for foo if __real_foo is referenced, and will be
144-
// true for __wrap_foo if foo is referenced).
145140
LLVM_PREFERRED_TYPE(bool)
146-
uint8_t referencedAfterWrap : 1;
141+
uint8_t ltoCanOmit : 1;
147142

148143
// True if this symbol is specified by --trace-symbol option.
149144
LLVM_PREFERRED_TYPE(bool)
@@ -333,6 +328,18 @@ class Symbol {
333328
LLVM_PREFERRED_TYPE(bool)
334329
uint8_t inDynamicList : 1;
335330

331+
// Used to track if there has been at least one undefined reference to the
332+
// symbol. For Undefined and SharedSymbol, the binding may change to STB_WEAK
333+
// if the first undefined reference from a non-shared object is weak.
334+
LLVM_PREFERRED_TYPE(bool)
335+
uint8_t referenced : 1;
336+
337+
// Used to track if this symbol will be referenced after wrapping is performed
338+
// (i.e. this will be true for foo if __real_foo is referenced, and will be
339+
// true for __wrap_foo if foo is referenced).
340+
LLVM_PREFERRED_TYPE(bool)
341+
uint8_t referencedAfterWrap : 1;
342+
336343
void setFlags(uint16_t bits) {
337344
flags.fetch_or(bits, std::memory_order_relaxed);
338345
}

lld/ELF/Writer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,9 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
297297
}
298298
}
299299

300-
if (ctx.arg.hasDynSymTab) {
301-
sym->exportDynamic = sym->includeInDynsym(ctx);
302-
sym->isPreemptible =
303-
sym->exportDynamic && computeIsPreemptible(ctx, *sym);
304-
}
300+
sym->isExported = sym->includeInDynsym(ctx);
301+
if (ctx.arg.hasDynSymTab)
302+
sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
305303
}
306304
}
307305

@@ -1891,7 +1889,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
18911889
if (ctx.in.symTab)
18921890
ctx.in.symTab->addSymbol(sym);
18931891

1894-
if (sym->exportDynamic) {
1892+
// computeBinding might localize a linker-synthesized hidden symbol
1893+
// (e.g. __global_pointer$) that was considered exported.
1894+
if (sym->isExported && !sym->isLocal()) {
18951895
ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
18961896
if (auto *file = dyn_cast<SharedFile>(sym->file))
18971897
if (file->isNeeded && !sym->isUndefined())

0 commit comments

Comments
 (0)