Don't set MustBeInDynSym for hidden symbols.
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 13 Apr 2016 19:03:34 +0000 (19:03 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 13 Apr 2016 19:03:34 +0000 (19:03 +0000)
llvm-svn: 266230

lld/ELF/Symbols.cpp
lld/test/ELF/dont-export-hidden.s [new file with mode: 0644]

index 4e9b623..9fe73b1 100644 (file)
@@ -218,10 +218,12 @@ int SymbolBody::compare(SymbolBody *Other) {
   if (L > R)
     return -Other->compare(this);
 
+  uint8_t V = getMinVisibility(getVisibility(), Other->getVisibility());
   if (isShared() != Other->isShared()) {
     SymbolBody *Shared = isShared() ? this : Other;
     Shared->MustBeInDynSym = true;
-    if (Shared->getVisibility() == STV_DEFAULT) {
+    if (Shared->getVisibility() == STV_DEFAULT &&
+        (V == STV_DEFAULT || V == STV_PROTECTED)) {
       // We want to export all symbols that exist in the executable and are
       // preemptable in DSOs, so that the symbols in the executable can
       // preempt symbols in the DSO at runtime.
@@ -231,7 +233,6 @@ int SymbolBody::compare(SymbolBody *Other) {
   }
 
   if (!isShared() && !Other->isShared()) {
-    uint8_t V = getMinVisibility(getVisibility(), Other->getVisibility());
     setVisibility(V);
     Other->setVisibility(V);
   }
diff --git a/lld/test/ELF/dont-export-hidden.s b/lld/test/ELF/dont-export-hidden.s
new file mode 100644 (file)
index 0000000..8819a6e
--- /dev/null
@@ -0,0 +1,39 @@
+// RUN: llvm-mc %p/Inputs/shared.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: ld.lld %t2.o %t.so -o %t.exe
+// RUN: llvm-readobj --dyn-symbols %t.exe | FileCheck %s
+
+        .global _start
+_start:
+        .global bar
+        .hidden bar
+bar:
+
+        .global bar2
+bar2:
+
+        .global foo
+foo:
+
+// 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:   Symbol {
+// CHECK-NEXT:     Name: bar2
+// CHECK-NEXT:     Value:
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Global
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 0
+// CHECK-NEXT:     Section: .text
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+