[lld] 2b129da - [ELF] Optimize parseSymbolVersion
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 8 12:33:02 PST 2024
Author: Fangrui Song
Date: 2024-12-08T12:32:55-08:00
New Revision: 2b129dacdde667137b5012d52f1d96e0ab26c749
URL: https://github.com/llvm/llvm-project/commit/2b129dacdde667137b5012d52f1d96e0ab26c749
DIFF: https://github.com/llvm/llvm-project/commit/2b129dacdde667137b5012d52f1d96e0ab26c749.diff
LOG: [ELF] Optimize parseSymbolVersion
We can just scan objectFiles and sharedFiles that have versioned symbols
to skip scanning the global symtab. While we won't suggest __wrap_foo
for undefined __wrap_foo at v1 when --wrap=foo at v1 is specified
(internalFile isn't scanned), this edge case difference is acceptable.
Added:
Modified:
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/ELF/SymbolTable.cpp
lld/test/ELF/symver.s
Removed:
################################################################################
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 9ff6ed58688cef..2006b3ba352070 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1217,6 +1217,7 @@ template <class ELFT> void ObjFile<ELFT>::postParse() {
Err(ctx) << "TLS attribute mismatch: " << &sym << "\n>>> in " << sym.file
<< "\n>>> in " << this;
+ hasVersionSyms |= sym.hasVersionSuffix;
// Handle non-COMMON defined symbol below. !sym.file allows a symbol
// assignment to redefine a symbol without an error.
if (!sym.isDefined() || secIdx == SHN_UNDEF)
@@ -1432,6 +1433,9 @@ template <class ELFT> void SharedFile::parse() {
const Elf_Shdr *verdefSec = nullptr;
const Elf_Shdr *verneedSec = nullptr;
+ numSymbols = numELFSyms;
+ symbols = std::make_unique<Symbol *[]>(numSymbols);
+
// Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
for (const Elf_Shdr &sec : sections) {
switch (sec.sh_type) {
@@ -1591,6 +1595,8 @@ template <class ELFT> void SharedFile::parse() {
s->dsoDefined = true;
if (s->file == this)
s->versionId = idx;
+ symbols[firstGlobal + i] = s;
+ hasVersionSyms = true;
}
}
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 79545c4bdeb5d0..f31256a4b516d7 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -242,6 +242,7 @@ class ELFFileBase : public InputFile {
StringRef sourceFile;
uint32_t andFeatures = 0;
bool hasCommonSyms = false;
+ bool hasVersionSyms = false;
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
};
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 648da94989d7a4..758ca882740e8d 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -353,9 +353,21 @@ void SymbolTable::scanVersionScript() {
// Symbol themselves might know their versions because symbols
// can contain versions in the form of <name>@<version>.
// Let them parse and update their names to exclude version suffix.
- for (Symbol *sym : symVector)
- if (sym->hasVersionSuffix)
- sym->parseSymbolVersion(ctx);
+ for (ELFFileBase *file : ctx.objectFiles) {
+ if (!file->hasVersionSyms)
+ continue;
+ for (Symbol *sym : file->getGlobalSymbols())
+ if (sym->hasVersionSuffix)
+ sym->parseSymbolVersion(ctx);
+ }
+ // Only used for undefined symbol suggestion.
+ for (ELFFileBase *file : ctx.sharedFiles) {
+ if (!file->hasVersionSyms)
+ continue;
+ for (Symbol *sym : file->getGlobalSymbols())
+ if (sym && sym->hasVersionSuffix)
+ sym->parseSymbolVersion(ctx);
+ }
// 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
diff --git a/lld/test/ELF/symver.s b/lld/test/ELF/symver.s
index d05fcc2a55d362..526fd2f2915948 100644
--- a/lld/test/ELF/symver.s
+++ b/lld/test/ELF/symver.s
@@ -139,8 +139,7 @@
# W3: error: undefined symbol: __wrap_foo at v1
# W3-NEXT: >>> referenced by {{.*}}ref1.o:(.text+0x1)
-# W3-NEXT: >>> did you mean: __wrap_foo{{$}}
-# W3-NEXT: >>> defined in: {{.*}}wrap.o
+# W3-NOT: {{.}}
## foo at v1 is correctly wrapped.
# RUN: ld.lld -shared --soname=t --version-script=%t/ver --wrap=foo at v1 %t/ref.o %t/ref1.o %t/def1.o %t/wrap1.o -o %t.w4
More information about the llvm-commits
mailing list