[PATCH] D35207: [ELF] - Give a symbol version extracted from name a priority over version set by script.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 10 09:14:22 PDT 2017


grimar created this revision.
Herald added a subscriber: emaste.

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.

Probably easiest way is to give .symver a priority over version script and do not reassign versions.
Looks bfd and gold do the same here.


https://reviews.llvm.org/D35207

Files:
  ELF/SymbolTable.cpp
  ELF/Symbols.cpp
  ELF/Symbols.h
  test/ELF/version-script-symver2.s


Index: test/ELF/version-script-symver2.s
===================================================================
--- test/ELF/version-script-symver2.s
+++ test/ELF/version-script-symver2.s
@@ -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
Index: ELF/Symbols.h
===================================================================
--- ELF/Symbols.h
+++ ELF/Symbols.h
@@ -363,8 +363,10 @@
   // True if this symbol is specified by --trace-symbol option.
   unsigned Traced : 1;
 
-  // This symbol version was found in a version script.
-  unsigned InVersionScript : 1;
+  // Symbols can have version baked in their names. If flag is true
+  // that means version was set from name, such version has priority
+  // over versions from script.
+  unsigned GotVersionFromName : 1;
 
   bool includeInDynsym() const;
   uint8_t computeBinding() const;
Index: ELF/Symbols.cpp
===================================================================
--- ELF/Symbols.cpp
+++ ELF/Symbols.cpp
@@ -253,6 +253,7 @@
   if (IsDefault)
     Verstr = Verstr.substr(1);
 
+  symbol()->GotVersionFromName = true;
   for (VersionDefinition &Ver : Config->VersionDefinitions) {
     if (Ver.Name != Verstr)
       continue;
Index: ELF/SymbolTable.cpp
===================================================================
--- ELF/SymbolTable.cpp
+++ ELF/SymbolTable.cpp
@@ -231,7 +231,7 @@
   Symbol *Sym;
   if (IsNew) {
     Sym = make<Symbol>();
-    Sym->InVersionScript = false;
+    Sym->GotVersionFromName = false;
     Sym->Binding = STB_WEAK;
     Sym->Visibility = STV_DEFAULT;
     Sym->IsUsedInRegularObj = false;
@@ -697,10 +697,11 @@
   // Assign the version.
   for (SymbolBody *B : Syms) {
     Symbol *Sym = B->symbol();
-    if (Sym->InVersionScript)
+    if (Sym->GotVersionFromName)
+      continue;
+    if (Sym->VersionId != Config->DefaultSymbolVersion)
       warn("duplicate symbol '" + Ver.Name + "' in version script");
     Sym->VersionId = VersionId;
-    Sym->InVersionScript = true;
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35207.105866.patch
Type: text/x-patch
Size: 2723 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170710/a878f636/attachment.bin>


More information about the llvm-commits mailing list