[lld] 8610cb0 - [ELF] -r: don't define _TLS_MODULE_BASE_

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 22 12:59:49 PST 2022


Author: Fangrui Song
Date: 2022-11-22T12:59:45-08:00
New Revision: 8610cb04605bbae3399972875aef69e5e457a879

URL: https://github.com/llvm/llvm-project/commit/8610cb04605bbae3399972875aef69e5e457a879
DIFF: https://github.com/llvm/llvm-project/commit/8610cb04605bbae3399972875aef69e5e457a879.diff

LOG: [ELF] -r: don't define _TLS_MODULE_BASE_

_TLS_MODULE_BASE_ is supposed to be defined by the final link. Defining it in a
relocatable link may render the final link value incorrect.

GNU ld i386/x86-64 have the same issue: https://sourceware.org/bugzilla/show_bug.cgi?id=29820

Added: 
    

Modified: 
    lld/ELF/Writer.cpp
    lld/test/ELF/x86-64-tlsdesc-ld.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 1098813a1114..eb5ebc8bdf8c 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1862,26 +1862,26 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
       addOptionalRegular("__global_pointer$", sec ? sec : Out::elfHeader, 0x800,
                          STV_DEFAULT);
     }
-  }
 
-  if (config->emachine == EM_386 || config->emachine == EM_X86_64) {
-    // On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
-    // way that:
-    //
-    // 1) Without relaxation: it produces a dynamic TLSDESC relocation that
-    // computes 0.
-    // 2) With LD->LE relaxation: _TLS_MODULE_BASE_ at tpoff = 0 (lowest address in
-    // the TLS block).
-    //
-    // 2) is special cased in @tpoff computation. To satisfy 1), we define it as
-    // an absolute symbol of zero. This is 
diff erent from GNU linkers which
-    // define _TLS_MODULE_BASE_ relative to the first TLS section.
-    Symbol *s = symtab.find("_TLS_MODULE_BASE_");
-    if (s && s->isUndefined()) {
-      s->resolve(Defined{/*file=*/nullptr, StringRef(), STB_GLOBAL, STV_HIDDEN,
-                         STT_TLS, /*value=*/0, 0,
-                         /*section=*/nullptr});
-      ElfSym::tlsModuleBase = cast<Defined>(s);
+    if (config->emachine == EM_386 || config->emachine == EM_X86_64) {
+      // On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
+      // way that:
+      //
+      // 1) Without relaxation: it produces a dynamic TLSDESC relocation that
+      // computes 0.
+      // 2) With LD->LE relaxation: _TLS_MODULE_BASE_ at tpoff = 0 (lowest address
+      // in the TLS block).
+      //
+      // 2) is special cased in @tpoff computation. To satisfy 1), we define it
+      // as an absolute symbol of zero. This is 
diff erent from GNU linkers which
+      // define _TLS_MODULE_BASE_ relative to the first TLS section.
+      Symbol *s = symtab.find("_TLS_MODULE_BASE_");
+      if (s && s->isUndefined()) {
+        s->resolve(Defined{/*file=*/nullptr, StringRef(), STB_GLOBAL,
+                           STV_HIDDEN, STT_TLS, /*value=*/0, 0,
+                           /*section=*/nullptr});
+        ElfSym::tlsModuleBase = cast<Defined>(s);
+      }
     }
   }
 

diff  --git a/lld/test/ELF/x86-64-tlsdesc-ld.s b/lld/test/ELF/x86-64-tlsdesc-ld.s
index 957decf54a4c..2f55aed4159b 100644
--- a/lld/test/ELF/x86-64-tlsdesc-ld.s
+++ b/lld/test/ELF/x86-64-tlsdesc-ld.s
@@ -32,6 +32,14 @@
 # LE-NEXT: movl %fs:-8(%rax), %edx
 # LE-NEXT: addl %fs:-4(%rax), %edx
 
+# RUN: ld.lld -r %t.o -o %t.ro
+# RUN: llvm-readelf -s %t.ro | FileCheck --check-prefix=RELOCATABLE %s
+# RUN: ld.lld %t.ro -o %t
+# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
+# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
+
+# RELOCATABLE: 0000000000000000 0 TLS GLOBAL DEFAULT UND _TLS_MODULE_BASE_
+
 leaq _TLS_MODULE_BASE_ at tlsdesc(%rip), %rax
 call *_TLS_MODULE_BASE_ at tlscall(%rax)
 movl %fs:a at dtpoff(%rax), %edx


        


More information about the llvm-commits mailing list