[lld] r299464 - Don't resolve hidden undef to a DSO.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 4 13:03:35 PDT 2017


Author: rafael
Date: Tue Apr  4 15:03:34 2017
New Revision: 299464

URL: http://llvm.org/viewvc/llvm-project?rev=299464&view=rev
Log:
Don't resolve hidden undef to a DSO.

The ELF spec says:

all of the non-default visibility attributes, when applied to a symbol
reference, imply that a definition to satisfy that reference must be
provided within the current executable or shared object.

But we were trying to resolve those undef references to shared
symbols. That causes odd results like creating a got entry with
a relocation pointing to 0.

Added:
    lld/trunk/test/ELF/hidden-vis-shared.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=299464&r1=299463&r2=299464&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Apr  4 15:03:34 2017
@@ -251,9 +251,13 @@ Symbol *SymbolTable<ELFT>::addUndefined(
                                         InputFile *File) {
   Symbol *S;
   bool WasInserted;
+  uint8_t Visibility = getVisibility(StOther);
   std::tie(S, WasInserted) =
-      insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, File);
-  if (WasInserted) {
+      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
+  // An undefined symbol with non default visibility must be satisfied
+  // in the same DSO.
+  if (WasInserted ||
+      (isa<SharedSymbol>(S->body()) && Visibility != STV_DEFAULT)) {
     S->Binding = Binding;
     replaceBody<Undefined>(S, Name, IsLocal, StOther, Type, File);
     return S;
@@ -428,7 +432,11 @@ void SymbolTable<ELFT>::addShared(Shared
   if (Sym.getVisibility() == STV_DEFAULT)
     S->ExportDynamic = true;
 
-  if (WasInserted || isa<Undefined>(S->body())) {
+  SymbolBody *Body = S->body();
+  // An undefined symbol with non default visibility must be satisfied
+  // in the same DSO.
+  if (WasInserted ||
+      (isa<Undefined>(Body) && Body->getVisibility() == STV_DEFAULT)) {
     replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(), &Sym,
                               Verdef);
     if (!S->isWeak())

Added: lld/trunk/test/ELF/hidden-vis-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/hidden-vis-shared.s?rev=299464&view=auto
==============================================================================
--- lld/trunk/test/ELF/hidden-vis-shared.s (added)
+++ lld/trunk/test/ELF/hidden-vis-shared.s Tue Apr  4 15:03:34 2017
@@ -0,0 +1,18 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-readobj -r %t | FileCheck %s
+// RUN: ld.lld %t2.so %t.o -o %t
+// RUN: llvm-readobj -r %t | FileCheck %s
+
+// CHECK:      Relocations [
+// CHECK-NEXT: ]
+
+.global _start
+_start:
+callq   bar
+.hidden bar
+.weak   bar




More information about the llvm-commits mailing list