[lld] [ELF] Fix -u with TLS symbols: propagate type from STT_NOTYPE to STT_TLS (PR #185794)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 20:03:15 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Fangrui Song (MaskRay)

<details>
<summary>Changes</summary>

-u creates an Undefined with STT_NOTYPE. When an object file provides
another Undefined with STT_TLS for the same symbol, Symbol::resolve
only updated binding, leaving type as STT_NOTYPE. This caused
sym.isTls() to return false in postScanRelocations, skipping TLS GOT
entry creation and leading to an out-of-range R_X86_64_GOTTPOFF error.

Fix: in resolve(Undefined), when the existing type is STT_NOTYPE,
adopt the incoming type.


---
Full diff: https://github.com/llvm/llvm-project/pull/185794.diff


2 Files Affected:

- (modified) lld/ELF/Symbols.cpp (+6) 
- (modified) lld/test/ELF/tls-mismatch.s (+7) 


``````````diff
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 220ec99c22e6f..d9c46c9d28d3a 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -501,6 +501,12 @@ void Symbol::resolve(Ctx &ctx, const Undefined &other) {
     // reference is weak.
     if (other.binding != STB_WEAK || !referenced)
       binding = other.binding;
+    // -u creates a placeholder Undefined (internalFile, STT_NOTYPE).
+    // Adopt the real file and type from the object file's undefined.
+    if (file == ctx.internalFile) {
+      file = other.file;
+      type = other.type;
+    }
   }
 }
 
diff --git a/lld/test/ELF/tls-mismatch.s b/lld/test/ELF/tls-mismatch.s
index 479879934ac75..161b1e5c94b62 100644
--- a/lld/test/ELF/tls-mismatch.s
+++ b/lld/test/ELF/tls-mismatch.s
@@ -31,6 +31,13 @@
 # RUN: ld.lld %t.o %t.bc -o /dev/null
 # RUN: ld.lld %t.bc %t.o -o /dev/null
 
+## -u creates an Undefined with STT_NOTYPE. The object file's STT_TLS undefined
+## should update the type so that the TLS IE GOT entry is correctly created.
+# RUN: ld.lld -shared -u tls1 %t1.o %t1.o -o %t1.so
+# RUN: llvm-readelf -rs %t1.so | FileCheck %s --check-prefix=UNDEF
+# UNDEF: R_X86_64_TPOFF64 {{.*}} tls1 + 0
+# UNDEF: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls1
+
 # CHECK: error: TLS attribute mismatch: tls1
 # CHECK-NEXT: >>> in {{.*}}.tmp.o
 # CHECK-NEXT: >>> in {{.*}}

``````````

</details>


https://github.com/llvm/llvm-project/pull/185794


More information about the llvm-commits mailing list