From: Fangrui Song Date: Tue, 21 Apr 2020 21:44:03 +0000 (-0700) Subject: [ELF] Fix a null pointer dereference when relocating a Local-Exec TLS relocation... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=01d2a01e79d3d83f18cf3e54c2bf55bba523b77a;p=platform%2Fupstream%2Fllvm.git [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. --- diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index e150cb8..b9b6fef 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 0474a41..0000000 --- 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 5a8791d..0000000 --- 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@gottpoff(%rip), %rax - .section .tbss,"awT",@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 0000000..fefda9d --- /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@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 1023aeb..0000000 --- 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@gottpoff(%rip), %rax - .section .tbss,"awT",@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 8feb267..4c8e1c5 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@tpoff+16(%rax), %rdx leaq global@tpoff+32(%rax), %rdx