[lld] 01d2a01 - [ELF] Fix a null pointer dereference when relocating a Local-Exec TLS relocation for a lazy symbol
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 21 15:40:19 PDT 2020
Author: Fangrui Song
Date: 2020-04-21T15:39:31-07:00
New Revision: 01d2a01e79d3d83f18cf3e54c2bf55bba523b77a
URL: https://github.com/llvm/llvm-project/commit/01d2a01e79d3d83f18cf3e54c2bf55bba523b77a
DIFF: https://github.com/llvm/llvm-project/commit/01d2a01e79d3d83f18cf3e54c2bf55bba523b77a.diff
LOG: [ELF] Fix a null pointer dereference when relocating a Local-Exec TLS relocation for a lazy symbol
If there is no SHF_TLS section, there will be no PT_TLS and Out::tlsPhdr may be a nullptr.
If the symbol referenced by an R_TLS is lazy, we should treat the symbol as undefined.
Also reorganize tls-in-archive.s and tls-weak-undef.s . They do not test what they intended to test.
Added:
lld/test/ELF/tls-le-weak-undef.s
Modified:
lld/ELF/InputSection.cpp
lld/test/ELF/x86-64-tls-le-undef.s
Removed:
lld/test/ELF/Inputs/tls-in-archive.s
lld/test/ELF/tls-in-archive.s
lld/test/ELF/tls-weak-undef.s
################################################################################
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index e150cb8f118d..b9b6fef9dc48 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -807,7 +807,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
// --noinhibit-exec, even a non-weak undefined reference may reach here.
// Just return A, which matches R_ABS, and the behavior of some dynamic
// loaders.
- if (sym.isUndefined())
+ if (sym.isUndefined() || sym.isLazy())
return a;
return getTlsTpOffset(sym) + a;
case R_RELAX_TLS_GD_TO_LE_NEG:
diff --git a/lld/test/ELF/Inputs/tls-in-archive.s b/lld/test/ELF/Inputs/tls-in-archive.s
deleted file mode 100644
index 0474a417659e..000000000000
--- a/lld/test/ELF/Inputs/tls-in-archive.s
+++ /dev/null
@@ -1,3 +0,0 @@
- .type foo, @tls_object
- .globl foo
-foo:
diff --git a/lld/test/ELF/tls-in-archive.s b/lld/test/ELF/tls-in-archive.s
deleted file mode 100644
index 5a8791dd2b3c..000000000000
--- a/lld/test/ELF/tls-in-archive.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// REQUIRES: x86
-// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o
-// RUN: rm -f %t.a
-// RUN: llvm-ar cru %t.a %t1.o
-// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
-// RUN: ld.lld %t2.o %t.a -o /dev/null
-
- .globl _start
-_start:
- movq foo at gottpoff(%rip), %rax
- .section .tbss,"awT", at nobits
- .weak foo
diff --git a/lld/test/ELF/tls-le-weak-undef.s b/lld/test/ELF/tls-le-weak-undef.s
new file mode 100644
index 000000000000..fefda9da9816
--- /dev/null
+++ b/lld/test/ELF/tls-le-weak-undef.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: echo '.tbss; .globl tls; tls:' | llvm-mc -filetype=obj -triple=x86_64 - -o %tdef.o
+# RUN: ld.lld %t.o -o - | llvm-objdump -d - | FileCheck %s
+
+## A weak symbol does not fetch a lazy definition.
+# RUN: ld.lld %t.o --start-lib %tdef.o --end-lib -o - | llvm-objdump -d - | FileCheck %s
+
+## Undefined TLS symbols arbitrarily resolve to 0.
+# CHECK: leaq 16(%rax), %rdx
+
+# RUN: ld.lld -shared %tdef.o -o %tdef.so
+# RUN: not ld.lld %t.o %tdef.so -o /dev/null 2>&1 | FileCheck --check-prefix=COPYRELOC %s
+
+# COPYRELOC: symbol 'tls' has no type
+
+.weak tls
+leaq tls at tpoff+16(%rax), %rdx
diff --git a/lld/test/ELF/tls-weak-undef.s b/lld/test/ELF/tls-weak-undef.s
deleted file mode 100644
index 1023aebbc258..000000000000
--- a/lld/test/ELF/tls-weak-undef.s
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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: rm -f %t.a
-// 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 at gottpoff(%rip), %rax
- .section .tbss,"awT", at nobits
- .weak foo
diff --git a/lld/test/ELF/x86-64-tls-le-undef.s b/lld/test/ELF/x86-64-tls-le-undef.s
index 8feb267c0915..4c8e1c59bd02 100644
--- a/lld/test/ELF/x86-64-tls-le-undef.s
+++ b/lld/test/ELF/x86-64-tls-le-undef.s
@@ -6,10 +6,7 @@
## Undefined TLS symbols resolve to 0.
## In --noinhibit-exec mode, a non-weak undefined symbol is not an error.
-# CHECK: leaq 16(%rax), %rdx
-# CHECK-NEXT: leaq 32(%rax), %rdx
+# CHECK: leaq 32(%rax), %rdx
-.weak weak
movq %fs:0, %rax
-leaq weak at tpoff+16(%rax), %rdx
leaq global at tpoff+32(%rax), %rdx
More information about the llvm-commits
mailing list