[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