diff options
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 7 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 10 | ||||
-rw-r--r-- | lld/test/elf2/tls-static.s | 5 |
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 |