[lld] r292146 - Give priority to linker scripts over preemption.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 16 09:35:24 PST 2017


Author: rafael
Date: Mon Jan 16 11:35:23 2017
New Revision: 292146

URL: http://llvm.org/viewvc/llvm-project?rev=292146&view=rev
Log:
Give priority to linker scripts over preemption.

LLD exports symbols that are also present in used shared libraries to
make sure they are preempted at runtime. That is a reasonable default,
but we must allow for it to be overwritten with linker script. If we
don't, libraries that expect to be able to hide a c++ delete operator
will fail.

This should fix the firebird build.

Added:
    lld/trunk/test/ELF/version-script-hide-so-symbol.s
Modified:
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/test/ELF/gc-sections-shared.s

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=292146&r1=292145&r2=292146&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Mon Jan 16 11:35:23 2017
@@ -426,12 +426,8 @@ void SymbolTable<ELFT>::addShared(Shared
   std::tie(S, WasInserted) =
       insert(Name, Sym.getType(), STV_DEFAULT, /*CanOmitFromDynSym*/ true, F);
   // Make sure we preempt DSO symbols with default visibility.
-  if (Sym.getVisibility() == STV_DEFAULT) {
+  if (Sym.getVisibility() == STV_DEFAULT)
     S->ExportDynamic = true;
-    // Exporting preempting symbols takes precedence over linker scripts.
-    if (S->VersionId == VER_NDX_LOCAL)
-      S->VersionId = VER_NDX_GLOBAL;
-  }
   if (WasInserted || isa<Undefined<ELFT>>(S->body())) {
     replaceBody<SharedSymbol<ELFT>>(S, F, Name, Sym, Verdef);
     if (!S->isWeak())

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=292146&r1=292145&r2=292146&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Mon Jan 16 11:35:23 2017
@@ -299,7 +299,8 @@ uint8_t Symbol::computeBinding() const {
     return Binding;
   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
     return STB_LOCAL;
-  if (VersionId == VER_NDX_LOCAL && !body()->isUndefined())
+  const SymbolBody *Body = body();
+  if (VersionId == VER_NDX_LOCAL && !Body->isUndefined() && !Body->isShared())
     return STB_LOCAL;
   if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE)
     return STB_GLOBAL;

Modified: lld/trunk/test/ELF/gc-sections-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gc-sections-shared.s?rev=292146&r1=292145&r2=292146&view=diff
==============================================================================
--- lld/trunk/test/ELF/gc-sections-shared.s (original)
+++ lld/trunk/test/ELF/gc-sections-shared.s Mon Jan 16 11:35:23 2017
@@ -19,15 +19,6 @@
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: bar
-# CHECK-NEXT:     Value:
-# CHECK-NEXT:     Size:
-# CHECK-NEXT:     Binding: Global
-# CHECK-NEXT:     Type:
-# CHECK-NEXT:     Other:
-# CHECK-NEXT:     Section: .text
-# CHECK-NEXT:   }
-# CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: bar2
 # CHECK-NEXT:     Value:
 # CHECK-NEXT:     Size:

Added: lld/trunk/test/ELF/version-script-hide-so-symbol.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/version-script-hide-so-symbol.s?rev=292146&view=auto
==============================================================================
--- lld/trunk/test/ELF/version-script-hide-so-symbol.s (added)
+++ lld/trunk/test/ELF/version-script-hide-so-symbol.s Mon Jan 16 11:35:23 2017
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t2.so
+# RUN: echo "{ local: *; };" > %t.script
+# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
+
+# The symbol foo must be hidden. This matches bfd and gold and is
+# required to make it possible for a c++ library to hide its own
+# operator delete.
+
+# CHECK:      DynamicSymbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: @ (0)
+# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: None
+# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Section: Undefined
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+        .global foo
+foo:
+	nop
+




More information about the llvm-commits mailing list