summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-04-25 00:15:48 +0000
committerRui Ueyama <ruiu@google.com>2017-04-25 00:15:48 +0000
commit321b9cd072c1738476e7269e624a6f807a9117f2 (patch)
treec719003871bc77fea92e857269c85745b7ca2350
parentbbebcb6c4d18b80a5bb0d0a3187624d61ebaa305 (diff)
downloadbcm5719-llvm-321b9cd072c1738476e7269e624a6f807a9117f2.tar.gz
bcm5719-llvm-321b9cd072c1738476e7269e624a6f807a9117f2.zip
Export __progname even if a -dynamic-list is given.
BSD's __progname symbol is defined in crt1.o and linked against main executables. The libc expects that main executables export __progname symbol via .dynsym sections. In order to handle this case, we scan undefined symbols in DSOs and exported them by setting Sym->ExportDynamic to true. But it turned out that setting that variable is not enough to make sure that symbols are exported in all use cases. If a -dynamic-list option is given, all symbols not explicitly mentioned in a version script are hidden by default. That hides __progname symbol. This patch fixes the issue. Fixes https://bugs.llvm.org/show_bug.cgi?id=32703 llvm-svn: 301282
-rw-r--r--lld/ELF/SymbolTable.cpp19
-rw-r--r--lld/test/ELF/progname.s4
2 files changed, 18 insertions, 5 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index a22f35e7b77..874e4efd9aa 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -548,11 +548,20 @@ template <class ELFT> void SymbolTable<ELFT>::scanUndefinedFlags() {
// shared libraries can find them.
// Except this, we ignore undefined symbols in DSOs.
template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() {
- for (SharedFile<ELFT> *File : SharedFiles)
- for (StringRef U : File->getUndefinedSymbols())
- if (SymbolBody *Sym = find(U))
- if (Sym->isDefined())
- Sym->symbol()->ExportDynamic = true;
+ for (SharedFile<ELFT> *File : SharedFiles) {
+ for (StringRef U : File->getUndefinedSymbols()) {
+ SymbolBody *Sym = find(U);
+ if (!Sym || !Sym->isDefined())
+ continue;
+ Sym->symbol()->ExportDynamic = true;
+
+ // If -dynamic-list is given, the default version is set to
+ // VER_NDX_LOCAL, which prevents a symbol to be exported via .dynsym.
+ // Set to VER_NDX_GLOBAL so the symbol will be handled as if it were
+ // specified by -dynamic-list.
+ Sym->symbol()->VersionId = VER_NDX_GLOBAL;
+ }
+ }
}
// Initialize DemangledSyms with a map from demangled symbols to symbol
diff --git a/lld/test/ELF/progname.s b/lld/test/ELF/progname.s
index a8837da69b5..ac2f918d800 100644
--- a/lld/test/ELF/progname.s
+++ b/lld/test/ELF/progname.s
@@ -12,6 +12,10 @@
// RUN: ld.lld -o %t %t.o %t.so
// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+// RUN: echo "{_start;};" > %t.dynlist
+// RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so
+// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
// CHECK: Name: __progname@
// CHECK-NEXT: Value: 0x201000
// CHECK-NEXT: Size: 0
OpenPOWER on IntegriCloud