diff options
| author | Rui Ueyama <ruiu@google.com> | 2017-04-25 00:15:48 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2017-04-25 00:15:48 +0000 |
| commit | 321b9cd072c1738476e7269e624a6f807a9117f2 (patch) | |
| tree | c719003871bc77fea92e857269c85745b7ca2350 | |
| parent | bbebcb6c4d18b80a5bb0d0a3187624d61ebaa305 (diff) | |
| download | bcm5719-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.cpp | 19 | ||||
| -rw-r--r-- | lld/test/ELF/progname.s | 4 |
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 |

