[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