[lld] r339042 - [ELF] Don't copy STT_TLS in copy relocation

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 6 12:09:40 PDT 2018


Author: maskray
Date: Mon Aug  6 12:09:40 2018
New Revision: 339042

URL: http://llvm.org/viewvc/llvm-project?rev=339042&view=rev
Log:
[ELF] Don't copy STT_TLS in copy relocation

During copy relocation of a variable defined in a DSO, if a TLS variable in that DSO happens to have the same st_value, it would also be copied. This was unnecessary because the addresses of TLS variables are relative to TLS segment. They don't interfere with non-TLS variables.

This copying behavior can be harmful in the following scenario:

For function-scope thread-local variables with non-trivial constructors,
they have guard variables. In the case of x86_64 general-dynamic model:

template <int N>
void foo() {
  thread_local std::string a;
}

GOT[n]   R_X86_64_DTPMOD64 guard variable for a
GOT[n+1] R_X86_64_DTPOFF64 guard variable for a
GOT[n+2] R_X86_64_DTPMOD64 a
GOT[n+3] R_X86_64_DTPOFF64 a

a and its guard variable are both represented as TLS variables, which
should be within the same module. If one is copy relocated to the main
module while the other is not, their module ID will mismatch and can
cause access without prior construction.

Reviewers: ruiu, espindola

Subscribers: emaste, arichardson, llvm-commits

Differential Revision: https://reviews.llvm.org/D50289

Added:
    lld/trunk/test/ELF/Inputs/copy-rel-tls.s
    lld/trunk/test/ELF/copy-rel-tls.s
Modified:
    lld/trunk/ELF/Relocations.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=339042&r1=339041&r2=339042&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Aug  6 12:09:40 2018
@@ -466,7 +466,7 @@ static SmallSet<SharedSymbol *, 4> getSy
   SmallSet<SharedSymbol *, 4> Ret;
   for (const Elf_Sym &S : File.getGlobalELFSyms()) {
     if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||
-        S.st_value != SS.Value)
+        S.getType() == STT_TLS || S.st_value != SS.Value)
       continue;
     StringRef Name = check(S.getName(File.getStringTable()));
     Symbol *Sym = Symtab->find(Name);

Added: lld/trunk/test/ELF/Inputs/copy-rel-tls.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/copy-rel-tls.s?rev=339042&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/copy-rel-tls.s (added)
+++ lld/trunk/test/ELF/Inputs/copy-rel-tls.s Mon Aug  6 12:09:40 2018
@@ -0,0 +1,12 @@
+.bss
+.global foo
+.type foo, @object
+.size foo, 4
+foo:
+
+.section .tbss,"awT", at nobits
+.global tfoo
+.skip 0x2000
+.type tfoo, at object
+.size tfoo, 4
+tfoo:

Added: lld/trunk/test/ELF/copy-rel-tls.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/copy-rel-tls.s?rev=339042&view=auto
==============================================================================
--- lld/trunk/test/ELF/copy-rel-tls.s (added)
+++ lld/trunk/test/ELF/copy-rel-tls.s Mon Aug  6 12:09:40 2018
@@ -0,0 +1,15 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-tls.s -o %t1.o
+// RUN: ld.lld %t1.o -shared -soname t1.so -o %t1.so
+// RUN: ld.lld %t.o %t1.so -o %t
+// RUN: llvm-nm %t1.so | FileCheck %s
+// RUN: llvm-nm %t | FileCheck --check-prefix=TLS %s
+// foo and tfoo have the same st_value but we should not copy tfoo.
+// CHECK: 2000 B foo
+// CHECK: 2000 B tfoo
+// TLS-NOT: tfoo
+
+.global _start
+_start:
+  leaq foo, %rax




More information about the llvm-commits mailing list