summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/SymbolTable.cpp7
-rw-r--r--lld/ELF/Writer.cpp10
-rw-r--r--lld/test/elf2/tls-static.s5
3 files changed, 13 insertions, 9 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 088bf5bca71..666755173cd 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -133,13 +133,6 @@ template <class ELFT> void SymbolTable::init(uint16_t EMachine) {
// Given that the symbol is effectively unused, we just create a dummy
// hidden one to avoid the undefined symbol error.
addIgnoredSym<ELFT>("_GLOBAL_OFFSET_TABLE_");
-
- // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
- // static linking the linker is required to optimize away any references to
- // __tls_get_addr, so it's not defined anywhere. Create a hidden definition
- // to avoid the undefined symbol error.
- if (Config->Static)
- addIgnoredSym<ELFT>("__tls_get_addr");
}
template <class ELFT> void SymbolTable::addELFFile(ELFFileBase *File) {
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index eff6cf159a9..e25089d99d5 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -105,9 +105,10 @@ private:
return !SymTabSec.getSymTable().getSharedFiles().empty() &&
!Config->DynamicLinker.empty();
}
- bool needsDynamicSections() const {
+ bool isOutputDynamic() const {
return !SymTabSec.getSymTable().getSharedFiles().empty() || Config->Shared;
}
+ bool needsDynamicSections() const { return isOutputDynamic(); }
unsigned getVAStart() const { return Config->Shared ? 0 : VAStart; }
std::unique_ptr<llvm::FileOutputBuffer> Buffer;
@@ -347,6 +348,13 @@ template <class ELFT> void Writer<ELFT>::createSections() {
AddStartEnd("__fini_array_start", "__fini_array_end",
DynamicSec.FiniArraySec);
+ // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
+ // static linking the linker is required to optimize away any references to
+ // __tls_get_addr, so it's not defined anywhere. Create a hidden definition
+ // to avoid the undefined symbol error.
+ if (!isOutputDynamic())
+ Symtab.addIgnoredSym<ELFT>("__tls_get_addr");
+
// FIXME: Try to avoid the extra walk over all global symbols.
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
for (auto &P : Symtab.getSymbols()) {
diff --git a/lld/test/elf2/tls-static.s b/lld/test/elf2/tls-static.s
index 6d4a2a48233..a681fc0fe87 100644
--- a/lld/test/elf2/tls-static.s
+++ b/lld/test/elf2/tls-static.s
@@ -1,8 +1,11 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared.s -o %tso
// RUN: lld -flavor gnu2 -static %t -o %tout
+// RUN: lld -flavor gnu2 %t -o %tout
+// RUN: lld -flavor gnu2 -shared %tso -o %tshared
+// RUN: not lld -flavor gnu2 -static %t %tshared -o %tout
// REQUIRES: x86
.global _start
-.text
_start:
call __tls_get_addr
OpenPOWER on IntegriCloud