[lld] r307792 - [ELF] - Give a symbol version extracted from name a priority over version set by script.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 12 06:54:42 PDT 2017


Author: grimar
Date: Wed Jul 12 06:54:42 2017
New Revision: 307792

URL: http://llvm.org/viewvc/llvm-project?rev=307792&view=rev
Log:
[ELF] - Give a symbol version extracted from name a priority over version set by script.

This fixes PR33712.

Imagine following script and code:

VER1 { global: foo; local: *; };
VER2 { global: foo; };

.global bar
bar:
.symver bar, foo at VER1

.global zed
zed:
.symver zed, foo@@VER2

We add foo@@VER2 as foo to symbol table, because have to resolve references to
foo for default symbols.
Later we are trying to assign symbol versions from script. For that we are searching for 'foo'
again. Here it is placed under VER1 and VER2 at the same time, we find it twice and trying to
set version again both times, hence LLD shows a warning.
Though sample code is correct: we have 2 different versions of foo.

Patch gives a symbol version extracted from name a priority over version set by script.

Differential revision: https://reviews.llvm.org/D35207

Added:
    lld/trunk/test/ELF/version-script-symver2.s
Modified:
    lld/trunk/ELF/SymbolTable.cpp

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=307792&r1=307791&r2=307792&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Jul 12 06:54:42 2017
@@ -695,6 +695,12 @@ void SymbolTable<ELFT>::assignExactVersi
 
   // Assign the version.
   for (SymbolBody *B : Syms) {
+    // Skip symbols containing version info because symbol versions
+    // specified by symbol names take precedence over version scripts.
+    // See parseSymbolVersion().
+    if (B->getName().find('@') != StringRef::npos)
+      continue;
+
     Symbol *Sym = B->symbol();
     if (Sym->VersionId != Config->DefaultSymbolVersion)
       warn("duplicate symbol '" + Ver.Name + "' in version script");
@@ -719,17 +725,9 @@ void SymbolTable<ELFT>::assignWildcardVe
 // This function processes version scripts by updating VersionId
 // member of symbols.
 template <class ELFT> void SymbolTable<ELFT>::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)
-    Sym->body()->parseSymbolVersion();
-
   // Handle edge cases first.
   handleAnonymousVersion();
 
-  if (Config->VersionDefinitions.empty())
-    return;
 
   // Now we have version definitions, so we need to set version ids to symbols.
   // Each version definition has a glob pattern, and all symbols that match
@@ -748,6 +746,12 @@ template <class ELFT> void SymbolTable<E
   for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
     for (SymbolVersion &Ver : V.Globals)
       assignWildcardVersion(Ver, V.Id);
+
+  // 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)
+    Sym->body()->parseSymbolVersion();
 }
 
 template class elf::SymbolTable<ELF32LE>;

Added: lld/trunk/test/ELF/version-script-symver2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/version-script-symver2.s?rev=307792&view=auto
==============================================================================
--- lld/trunk/test/ELF/version-script-symver2.s (added)
+++ lld/trunk/test/ELF/version-script-symver2.s Wed Jul 12 06:54:42 2017
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "VER1 { global: foo; local: *; }; VER2 { global: foo; }; VER3 { global: foo; };" > %t.map
+# RUN: ld.lld -shared %t.o --version-script %t.map -o %t.so --fatal-warnings
+# RUN: llvm-readobj -V %t.so | FileCheck %s
+
+# CHECK:      Symbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Version: 0
+# CHECK-NEXT:     Name: @
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Version: 3
+# CHECK-NEXT:     Name: foo@@VER2
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Version: 2
+# CHECK-NEXT:     Name: foo at VER1
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+.global bar
+bar:
+.symver bar, foo at VER1
+
+.global zed
+zed:
+.symver zed, foo@@VER2




More information about the llvm-commits mailing list