[lld] 21ac457 - [ELF] Priorize the last catch-all pattern in version scripts
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 9 23:47:06 PDT 2023
Author: Fangrui Song
Date: 2023-09-09T23:47:01-07:00
New Revision: 21ac457f3f8f707b6eb79f15f52d366a31ee4385
URL: https://github.com/llvm/llvm-project/commit/21ac457f3f8f707b6eb79f15f52d366a31ee4385
DIFF: https://github.com/llvm/llvm-project/commit/21ac457f3f8f707b6eb79f15f52d366a31ee4385.diff
LOG: [ELF] Priorize the last catch-all pattern in version scripts
When there are multiple catch-all patterns (i.e. a single `*`), GNU ld and gold
select the last pattern. Match their behavior.
This change was inspired by a correction made by Michael Kerrisk to a blog post
I wrote at https://maskray.me/blog/2020-11-26-all-about-symbol-versioning ,
following the current lld rules.
Note: GNU ld prefers global: patterns to local: patterns, which might seem
awkward (https://www.airs.com/blog/archives/300). gold doesn't follow this
behavior, and we do not either.
Added:
Modified:
lld/ELF/SymbolTable.cpp
lld/test/ELF/version-script-reassign-glob.s
Removed:
################################################################################
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 0437095c8638150..fe7edd5b0eb49aa 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -313,7 +313,7 @@ void SymbolTable::scanVersionScript() {
// Then, assign versions to "*". In GNU linkers they have lower priority than
// other wildcards.
- for (VersionDefinition &v : config->versionDefinitions) {
+ for (VersionDefinition &v : llvm::reverse(config->versionDefinitions)) {
for (SymbolVersion &pat : v.nonLocalPatterns)
if (pat.hasWildcard && pat.name == "*")
assignWildcard(pat, v.id, v.name);
diff --git a/lld/test/ELF/version-script-reassign-glob.s b/lld/test/ELF/version-script-reassign-glob.s
index e25cdacae89a9fc..39d19a26fc44984 100644
--- a/lld/test/ELF/version-script-reassign-glob.s
+++ b/lld/test/ELF/version-script-reassign-glob.s
@@ -9,11 +9,18 @@
# RUN: ld.lld --version-script %t.ver %t.o -shared -o %t.so --fatal-warnings
# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=BAR %s
+# RUN: echo 'bar1 { *; }; bar2 { *; };' > %t2.ver
+# RUN: ld.lld --version-script %t2.ver %t.o -shared -o %t2.so --fatal-warnings
+# RUN: llvm-readelf --dyn-syms %t2.so | FileCheck --check-prefix=BAR2 %s
+
## If both a non-* glob and a * match, non-* wins.
## This is GNU linkers' behavior. We don't feel strongly this should be supported.
# FOO: GLOBAL DEFAULT 7 foo@@foo
# BAR: GLOBAL DEFAULT 7 foo@@bar
+## When there are multiple * patterns, the last wins.
+# BAR2: GLOBAL DEFAULT 7 foo@@bar2
+
.globl foo
foo:
More information about the llvm-commits
mailing list