From 03f7005375c2624538af42e8d6e8a8b7e13b6000 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Fri, 23 Sep 2016 18:47:50 +0000 Subject: [PATCH] [ELF] Resolve weak undefined TLS symbols when no phdr is available. If we pass --gc-sections to lld and .tbss is not referenced, the section is reclaimed and lld doesn't create a TLS program header. R_TLS tries to access the program header -> lld crashes. Mimic what bfd/gold do in this case and resolve a weak undefined TLS symbol to the base of the TLS block, i.e. give it a value of zero. Differential Revision: https://reviews.llvm.org/D24832 llvm-svn: 282279 --- lld/ELF/InputSection.cpp | 8 ++++++++ lld/test/ELF/tls-weak-undef.s | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 lld/test/ELF/tls-weak-undef.s diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 3cc6ce5..36b7748 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -241,6 +241,14 @@ static typename ELFT::uint getSymVA(uint32_t Type, typename ELFT::uint A, case R_RELAX_TLS_IE_TO_LE: case R_RELAX_TLS_GD_TO_LE: case R_TLS: + // A weak undefined TLS symbol resolves to the base of the TLS + // block, i.e. gets a value of zero. If we pass --gc-sections to + // lld and .tbss is not referenced, it gets reclaimed and we don't + // create a TLS program header. Therefore, we resolve this + // statically to zero. + if (Body.isTls() && (Body.isLazy() || Body.isUndefined()) && + Body.symbol()->isWeak()) + return 0; if (Target->TcbSize) return Body.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align); diff --git a/lld/test/ELF/tls-weak-undef.s b/lld/test/ELF/tls-weak-undef.s new file mode 100644 index 0000000..7aa6ef1 --- /dev/null +++ b/lld/test/ELF/tls-weak-undef.s @@ -0,0 +1,16 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t --gc-sections + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ +// RUN: %p/Inputs/tls-in-archive.s -o %t1.o +// RUN: llvm-ar cru %t.a %t1.o +// RUN: ld.lld %t.o %t.a -o %t + +// Check that lld doesn't crash because we don't reference +// the TLS phdr when it's not created. + .globl _start +_start: + movq foo@gottpoff(%rip), %rax + .section .tbss,"awT",@nobits + .weak foo -- 2.7.4