aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2025-01-26 20:32:42 -0800
committerFangrui Song <i@maskray.me>2025-01-26 20:32:43 -0800
commit2a26292388fcab0c857c91b2d08074c33abd37e8 (patch)
tree0349518a606b2ee558b8a122a44861b4958c5770
parent0e6b58202ca9c4d1ca814e4bea5bd3f0bac7f329 (diff)
downloadllvm-2a26292388fcab0c857c91b2d08074c33abd37e8.zip
llvm-2a26292388fcab0c857c91b2d08074c33abd37e8.tar.gz
llvm-2a26292388fcab0c857c91b2d08074c33abd37e8.tar.bz2
[ELF] Make isExported accurate early
LTO compilation might define symbols not in the symbol table (e.g. __emutls_v.x in test/ELF/lto/wrap-unreferenced-before-codegen.test). These symbols have a false `isExported` until `demoteSymbolsAndComputeIsPreemptible`. This is usually benign as we do not reference `isExported` that early. Ensure that `isExported` is correct early. This helps remove a redundant `isExported` computation in `demoteSymbolsAndComputeIsPreemptible`.
-rw-r--r--lld/ELF/Driver.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 7e0d3fc..06c9371 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2157,9 +2157,12 @@ static void excludeLibs(Ctx &ctx, opt::InputArgList &args) {
ArrayRef<Symbol *> symbols = file->getSymbols();
if (isa<ELFFileBase>(file))
symbols = cast<ELFFileBase>(file)->getGlobalSymbols();
- for (Symbol *sym : symbols)
- if (!sym->isUndefined() && sym->file == file)
+ for (Symbol *sym : symbols) {
+ if (!sym->isUndefined() && sym->file == file) {
sym->versionId = VER_NDX_LOCAL;
+ sym->isExported = false;
+ }
+ }
};
for (ELFFileBase *file : ctx.objectFiles)
@@ -2545,11 +2548,17 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
auto *obj = cast<ObjFile<ELFT>>(file.get());
obj->parse(/*ignoreComdats=*/true);
- // Parse '@' in symbol names for non-relocatable output.
+ // For defined symbols in non-relocatable output,
+ // compute isExported and parse '@'.
if (!ctx.arg.relocatable)
- for (Symbol *sym : obj->getGlobalSymbols())
+ for (Symbol *sym : obj->getGlobalSymbols()) {
+ if (!sym->isDefined())
+ continue;
+ if (sym->includeInDynsym(ctx))
+ sym->isExported = true;
if (sym->hasVersionSuffix)
sym->parseSymbolVersion(ctx);
+ }
ctx.objectFiles.push_back(obj);
}
}
@@ -3061,7 +3070,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Handle --exclude-libs again because lto.tmp may reference additional
// libcalls symbols defined in an excluded archive. This may override
- // versionId set by scanVersionScript().
+ // versionId set by scanVersionScript() and isExported.
if (args.hasArg(OPT_exclude_libs))
excludeLibs(ctx, args);