[lld] r291293 - Handle versioned undefined symbols.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 6 14:30:36 PST 2017


Author: rafael
Date: Fri Jan  6 16:30:35 2017
New Revision: 291293

URL: http://llvm.org/viewvc/llvm-project?rev=291293&view=rev
Log:
Handle versioned undefined symbols.

In order to keep symbol lookup a simple name lookup this patch adds
versioned symbols with an explicit @ to the symbol table.

Added:
    lld/trunk/test/ELF/undefined-versioned-symbol.s
Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/Symbols.cpp

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=291293&r1=291292&r2=291293&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Jan  6 16:30:35 2017
@@ -651,6 +651,8 @@ template <class ELFT> void SharedFile<EL
       VersymIndex = Versym->vs_index;
       ++Versym;
     }
+    bool Hidden = VersymIndex & VERSYM_HIDDEN;
+    VersymIndex = VersymIndex & ~VERSYM_HIDDEN;
 
     StringRef Name = check(Sym.getName(this->StringTable));
     if (Sym.isUndefined()) {
@@ -658,15 +660,23 @@ template <class ELFT> void SharedFile<EL
       continue;
     }
 
-    if (Versym) {
-      // Ignore local symbols and non-default versions.
-      if (VersymIndex == VER_NDX_LOCAL || (VersymIndex & VERSYM_HIDDEN))
-        continue;
-    }
+    // Ignore local symbols.
+    if (Versym && VersymIndex == VER_NDX_LOCAL)
+      continue;
 
     const Elf_Verdef *V =
         VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex];
-    elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+
+    if (!Hidden)
+      elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+
+    // Also add the symbol with the versioned name to handle undefined symbols
+    // with explicit versions.
+    if (V) {
+      StringRef VerName = this->StringTable.data() + V->getAux()->vda_name;
+      Name = Saver.save(Twine(Name) + "@" + VerName);
+      elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+    }
   }
 }
 

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=291293&r1=291292&r2=291293&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Jan  6 16:30:35 2017
@@ -202,6 +202,10 @@ void SymbolBody::parseSymbolVersion() {
   // Truncate the symbol name so that it doesn't include the version string.
   Name = {S.data(), Pos};
 
+  // If this is an undefined or shared symbol it is not a definition.
+  if (isUndefined() || isShared())
+    return;
+
   // '@@' in a symbol name means the default version.
   // It is usually the most recent one.
   bool IsDefault = (Verstr[0] == '@');

Added: lld/trunk/test/ELF/undefined-versioned-symbol.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/undefined-versioned-symbol.s?rev=291293&view=auto
==============================================================================
--- lld/trunk/test/ELF/undefined-versioned-symbol.s (added)
+++ lld/trunk/test/ELF/undefined-versioned-symbol.s Fri Jan  6 16:30:35 2017
@@ -0,0 +1,74 @@
+// REQUIRES: x86
+// RUN: echo ".data; \
+// RUN:       .quad \"basename\"; \
+// RUN:       .quad \"basename at FBSD_1.0\"; \
+// RUN:       .quad \"basename at FBSD_1.1\" " > %t.s
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
+// RUN: echo "FBSD_1.0 { local: *; }; FBSD_1.1 { };" > %t2.ver
+// RUN: ld.lld --shared --version-script %t2.ver %t2.o -o %t2.so
+// RUN: echo "LIBPKG_1.3 { };" > %t.ver
+// RUN: ld.lld --shared %t.o --version-script %t.ver %t2.so -o %t.so
+// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t.so | FileCheck %s
+
+// Test that each relocation points to the correct version.
+
+// CHECK:      Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT:   Relocation {
+// CHECK-NEXT:     Offset: 0x2000
+// CHECK-NEXT:     Type: R_X86_64_64 (1)
+// CHECK-NEXT:     Symbol: basename (1)
+// CHECK-NEXT:     Addend: 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Relocation {
+// CHECK-NEXT:     Offset: 0x2008
+// CHECK-NEXT:     Type: R_X86_64_64 (1)
+// CHECK-NEXT:     Symbol: basename (2)
+// CHECK-NEXT:     Addend: 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Relocation {
+// CHECK-NEXT:     Offset: 0x2010
+// CHECK-NEXT:     Type: R_X86_64_64 (1)
+// CHECK-NEXT:     Symbol: basename (3)
+// CHECK-NEXT:     Addend: 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: }
+
+
+// CHECK:      DynamicSymbols [
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name:
+// CHECK-NEXT:     Value:
+// CHECK-NEXT:     Size:
+// CHECK-NEXT:     Binding:
+// CHECK-NEXT:     Type:
+// CHECK-NEXT:     Other:
+// CHECK-NEXT:     Section:
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: basename at FBSD_1.1
+// CHECK-NEXT:     Value:
+// CHECK-NEXT:     Size:
+// CHECK-NEXT:     Binding:
+// CHECK-NEXT:     Type:
+// CHECK-NEXT:     Other:
+// CHECK-NEXT:     Section:
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: basename at FBSD_1.0
+// CHECK-NEXT:     Value:
+// CHECK-NEXT:     Size:
+// CHECK-NEXT:     Binding:
+// CHECK-NEXT:     Type:
+// CHECK-NEXT:     Other:
+// CHECK-NEXT:     Section:
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: basename at FBSD_1.1
+
+
+.global "basename at FBSD_1.0"
+"basename at FBSD_1.0":
+
+.global "basename@@FBSD_1.1"
+"basename@@FBSD_1.1":




More information about the llvm-commits mailing list