[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