summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2016-09-23 18:47:50 +0000
committerDavide Italiano <davide@freebsd.org>2016-09-23 18:47:50 +0000
commit03f7005375c2624538af42e8d6e8a8b7e13b6000 (patch)
treeb8bdf37fc98b40870968b5ffbdad7aea8401ec2f
parent04949faf69ad46ed97d7276a3a7d7e762f5b8f77 (diff)
downloadbcm5719-llvm-03f7005375c2624538af42e8d6e8a8b7e13b6000.tar.gz
bcm5719-llvm-03f7005375c2624538af42e8d6e8a8b7e13b6000.zip
[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
-rw-r--r--lld/ELF/InputSection.cpp8
-rw-r--r--lld/test/ELF/tls-weak-undef.s16
2 files changed, 24 insertions, 0 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 3cc6ce58245..36b7748a4d2 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<ELFT>(A) +
alignTo(Target->TcbSize, Out<ELFT>::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 00000000000..7aa6ef13a2a
--- /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
OpenPOWER on IntegriCloud