[lld] r365759 - [ELF] Warn rather than error when duplicate version assignments occur

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 11 04:16:45 PDT 2019


Author: maskray
Date: Thu Jul 11 04:16:44 2019
New Revision: 365759

URL: http://llvm.org/viewvc/llvm-project?rev=365759&view=rev
Log:
[ELF] Warn rather than error when duplicate version assignments occur

In lvm2, libdevmapper.so is linked with a version script with duplicate
version assignments:

    DM_1_02_138 { global: ... dm_bitset_parse_list; ... };
    DM_1_02_129 { global: ... dm_bitset_parse_list; ... };

ld.bfd silently accepts this while gold issues a warning. We currently
error, thus inhibit producing the executable. Change the error to
warning to allow this case, and improve the message.

There are some cases where ld.bfd error
`anonymous version tag cannot be combined with other version tags`
but we just warn. It is probably OK for now.

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D64549

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

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=365759&r1=365758&r2=365759&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Jul 11 04:16:44 2019
@@ -201,6 +201,14 @@ void SymbolTable::assignExactVersion(Sym
     return;
   }
 
+  auto getName = [](uint16_t ver) -> std::string {
+    if (ver == VER_NDX_LOCAL)
+      return "VER_NDX_LOCAL";
+    if (ver == VER_NDX_GLOBAL)
+      return "VER_NDX_GLOBAL";
+    return ("version '" + config->versionDefinitions[ver - 2].name + "'").str();
+  };
+
   // Assign the version.
   for (Symbol *sym : syms) {
     // Skip symbols containing version info because symbol versions
@@ -209,10 +217,13 @@ void SymbolTable::assignExactVersion(Sym
     if (sym->getName().contains('@'))
       continue;
 
-    if (sym->versionId != config->defaultSymbolVersion &&
-        sym->versionId != versionId)
-      error("duplicate symbol '" + ver.name + "' in version script");
-    sym->versionId = versionId;
+    if (sym->versionId == config->defaultSymbolVersion)
+      sym->versionId = versionId;
+    if (sym->versionId == versionId)
+      continue;
+
+    warn("attempt to reassign symbol '" + ver.name + "' of " +
+         getName(sym->versionId) + " to " + getName(versionId));
   }
 }
 

Added: lld/trunk/test/ELF/version-script-reassign.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/version-script-reassign.s?rev=365759&view=auto
==============================================================================
--- lld/trunk/test/ELF/version-script-reassign.s (added)
+++ lld/trunk/test/ELF/version-script-reassign.s Thu Jul 11 04:16:44 2019
@@ -0,0 +1,31 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: echo '{ local: foo; };' > %tl.ver
+# RUN: echo '{ global: foo; local: *; };' > %tg.ver
+# RUN: echo 'V1 { global: foo; };' > %t1.ver
+# RUN: echo 'V2 { global: foo; };' > %t2.ver
+
+## Note, ld.bfd errors on the two cases.
+# RUN: ld.lld -shared %t.o --version-script %tl.ver --version-script %t1.ver \
+# RUN:   -o %t.so 2>&1 | FileCheck --check-prefix=LOCAL %s
+# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=LOCAL-SYM %s
+# RUN: ld.lld -shared %t.o --version-script %tg.ver --version-script %t1.ver \
+# RUN:   -o %t.so 2>&1 | FileCheck --check-prefix=GLOBAL %s
+# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=GLOBAL-SYM %s
+
+## Note, ld.bfd silently accepts this case.
+# RUN: ld.lld -shared %t.o --version-script %t1.ver --version-script %t2.ver \
+# RUN:   -o %t.so 2>&1 | FileCheck --check-prefix=V1-WARN %s
+# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=V1-SYM %s
+
+# LOCAL: warning: attempt to reassign symbol 'foo' of VER_NDX_LOCAL to version 'V1'
+# LOCAL-SYM-NOT: foo
+
+# GLOBAL: warning: attempt to reassign symbol 'foo' of VER_NDX_GLOBAL to version 'V1'
+# GLOBAL-SYM: foo{{$}}
+
+# V1-WARN: warning: attempt to reassign symbol 'foo' of version 'V1' to version 'V2'
+# V1-SYM: foo@@V1
+
+.globl foo
+foo:

Modified: lld/trunk/test/ELF/version-script.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/version-script.s?rev=365759&r1=365758&r2=365759&view=diff
==============================================================================
--- lld/trunk/test/ELF/version-script.s (original)
+++ lld/trunk/test/ELF/version-script.s Thu Jul 11 04:16:44 2019
@@ -32,12 +32,6 @@
 # RUN:   FileCheck -check-prefix=ERR2 %s
 # ERR2: EOF expected, but got VERSION_2.0
 
-# RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t6.script
-# RUN: echo "VERSION_2.0 { global: foo1; local: *; };" >> %t6.script
-# RUN: not ld.lld --version-script %t6.script -shared %t.o %t2.so -o /dev/null 2>&1 | \
-# RUN:   FileCheck -check-prefix=ERR3 %s
-# ERR3: duplicate symbol 'foo1' in version script
-
 # RUN: echo "{ foo1; foo2; };" > %t.list
 # RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2
 # RUN: llvm-readobj %t2 > /dev/null




More information about the llvm-commits mailing list