summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-04-29 17:46:07 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-04-29 17:46:07 +0000
commitfb4f2fedd1e4402f1d8a933813c2addb83d07e24 (patch)
treebab7b27efa2a7ce2b8695d7ea64780769b37b893
parent74ca1cc7d01e2865cb14ab73a7121999fb63f596 (diff)
downloadbcm5719-llvm-fb4f2fedd1e4402f1d8a933813c2addb83d07e24.tar.gz
bcm5719-llvm-fb4f2fedd1e4402f1d8a933813c2addb83d07e24.zip
Be sure to always increment the Versym pointer.
It was getting out of sync if we had undefined symbols at the start of the symbol table. llvm-svn: 268077
-rw-r--r--lld/ELF/InputFiles.cpp9
-rwxr-xr-xlld/test/ELF/Inputs/version-undef-sym.sobin0 -> 2312 bytes
-rw-r--r--lld/test/ELF/version-undef-sym.s21
3 files changed, 27 insertions, 3 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index a4b5b718e38..2c7124e6a05 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -490,16 +490,19 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
SymbolBodies.reserve(NumSymbols);
for (const Elf_Sym &Sym : Syms) {
+ unsigned VersymIndex = 0;
+ if (Versym) {
+ VersymIndex = Versym->vs_index;
+ ++Versym;
+ }
+
StringRef Name = check(Sym.getName(this->StringTable));
if (Sym.isUndefined()) {
Undefs.push_back(Name);
continue;
}
- unsigned VersymIndex = 0;
if (Versym) {
- VersymIndex = Versym->vs_index;
- ++Versym;
// Ignore local symbols and non-default versions.
if (VersymIndex == 0 || (VersymIndex & VERSYM_HIDDEN))
continue;
diff --git a/lld/test/ELF/Inputs/version-undef-sym.so b/lld/test/ELF/Inputs/version-undef-sym.so
new file mode 100755
index 00000000000..abb4399cd6c
--- /dev/null
+++ b/lld/test/ELF/Inputs/version-undef-sym.so
Binary files differ
diff --git a/lld/test/ELF/version-undef-sym.s b/lld/test/ELF/version-undef-sym.s
new file mode 100644
index 00000000000..bdb4795fd1f
--- /dev/null
+++ b/lld/test/ELF/version-undef-sym.s
@@ -0,0 +1,21 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-readobj --dyn-symbols %p/Inputs/version-undef-sym.so | FileCheck %s
+
+
+// Show that the input .so has undefined symbols before bar. That is what would
+// get our version parsing out of sync.
+
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Name: bar
+
+// But now we can successfully find bar.
+// RUN: ld.lld %t %p/Inputs/version-undef-sym.so -o %t.exe
+
+ .global _start
+_start:
+ call bar@plt
OpenPOWER on IntegriCloud