[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