[llvm-branch-commits] [lld] release/23.x: [LLD][COFF] Replace ARM64EC TLS directory chunks with native chunks when available (#212845) (PR #213533)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Aug 2 04:53:25 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-platform-windows
Author: llvmbot
<details>
<summary>Changes</summary>
Backport e096d2f60dbc6cab991d5c02a5f7125a6dc694dc
Requested by: @<!-- -->cjacek
---
Full diff: https://github.com/llvm/llvm-project/pull/213533.diff
3 Files Affected:
- (modified) lld/COFF/Chunks.h (+2-1)
- (modified) lld/COFF/Driver.cpp (+24-3)
- (added) lld/test/COFF/arm64x-tls.s (+121)
``````````diff
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index fd2948fc31eb1..a0628654b94e4 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -394,11 +394,12 @@ class SectionChunk : public Chunk {
// and this chunk is considered as dead.
SectionChunk *repl;
+ void replace(SectionChunk *other);
+
private:
SectionChunk *assocChildren = nullptr;
// Used for ICF (Identical COMDAT Folding)
- void replace(SectionChunk *other);
uint32_t eqClass[2] = {0, 0};
// Relocations for this section. Size is stored below.
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 4eedefbf2ba5e..9d39aff73601b 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2805,9 +2805,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
ltoCompilationDone = true;
ctx.forEachSymtab([](SymbolTable &symtab) { symtab.compileBitcodeFiles(); });
- if (Defined *d =
- dyn_cast_or_null<Defined>(ctx.symtab.findUnderscore("_tls_used")))
- config->gcroot.push_back(d);
+ ctx.forEachSymtab([&](SymbolTable &symtab) {
+ if (Defined *d =
+ dyn_cast_or_null<Defined>(symtab.findUnderscore("_tls_used")))
+ config->gcroot.push_back(d);
+ });
// If -thinlto-index-only is given, we should create only "index
// files" and not object files. Index file creation is already done
@@ -2837,6 +2839,25 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (errorCount())
return;
+ if (ctx.hybridSymtab) {
+ // On ARM64X, merge tls chunks, there may be only one true _tls_start and
+ // _tls_end chunk. Additionally, both views use the same _tls_used and
+ // _tls_index.
+ auto maybeReplaceWithNative = [&](StringRef name) {
+ auto nativeSym = dyn_cast_or_null<DefinedRegular>(
+ ctx.hybridSymtab->findUnderscore(name));
+ if (!nativeSym)
+ return;
+ if (auto ecSym =
+ dyn_cast_or_null<DefinedRegular>(ctx.symtab.findUnderscore(name)))
+ nativeSym->getChunk()->replace(ecSym->getChunk());
+ };
+ maybeReplaceWithNative("_tls_used");
+ maybeReplaceWithNative("_tls_index");
+ maybeReplaceWithNative("_tls_start");
+ maybeReplaceWithNative("_tls_end");
+ }
+
ctx.forEachActiveSymtab([](SymbolTable &symtab) {
symtab.initializeECThunks();
symtab.initializeLoadConfig();
diff --git a/lld/test/COFF/arm64x-tls.s b/lld/test/COFF/arm64x-tls.s
new file mode 100644
index 0000000000000..608604fab2fb3
--- /dev/null
+++ b/lld/test/COFF/arm64x-tls.s
@@ -0,0 +1,121 @@
+// REQUIRES: aarch64
+// RUN: split-file %s %t.dir && cd %t.dir
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows aarch64.s -o aarch64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64ec.s -o arm64ec.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows tls-aarch64.s -o tls-aarch64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows tls-arm64ec.s -o tls-arm64ec.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
+
+// RUN: rm -f tls.lib
+// RUN: llvm-lib -machine:arm64x -out:tls.lib tls-aarch64.obj tls-arm64ec.obj loadconfig-arm64ec.obj loadconfig-arm64.obj
+// RUN: lld-link -machine:arm64x -dll -noentry aarch64.obj arm64ec.obj tls.lib -out:out.dll
+
+// Check that we're using native _tls_index and _tls_used for both views.
+
+// RUN: llvm-readobj --coff-tls-directory --hex-dump=.ec --hex-dump=.a64 out.dll | FileCheck %s
+// CHECK: Format: COFF-ARM64X
+// CHECK-NEXT: Arch: aarch64
+// CHECK-NEXT: AddressSize: 64bit
+// CHECK-EMPTY:
+// CHECK-NEXT: Hex dump of section '.a64':
+// CHECK-NEXT: 0x180004000 00500000 04500000 00700000 01700000
+// CHECK-EMPTY:
+// CHECK-NEXT: Hex dump of section '.ec':
+// CHECK-NEXT: 0x180006000 00500000 04500000 00700000 01700000
+// CHECK-NEXT: TLSDirectory {
+// CHECK-NEXT: StartAddressOfRawData: 0x180007000
+// CHECK-NEXT: EndAddressOfRawData: 0x180007001
+// CHECK-NEXT: AddressOfIndex: 0x180005000
+// CHECK-NEXT: AddressOfCallBacks: 0x0
+// CHECK-NEXT: SizeOfZeroFill: 0x0
+// CHECK-NEXT: Characteristics [ (0x100000)
+// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES (0x100000)
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
+// CHECK-NEXT: HybridObject {
+// CHECK-NEXT: Format: COFF-ARM64EC
+// CHECK-NEXT: Arch: aarch64
+// CHECK-NEXT: AddressSize: 64bit
+// CHECK-EMPTY:
+// CHECK-NEXT: Hex dump of section '.a64':
+// CHECK-NEXT: 0x180004000 00500000 04500000 00700000 01700000
+// CHECK-EMPTY:
+// CHECK-NEXT: Hex dump of section '.ec':
+// CHECK-NEXT: 0x180006000 00500000 04500000 00700000 01700000
+// CHECK-NEXT: TLSDirectory {
+// CHECK-NEXT: StartAddressOfRawData: 0x180007000
+// CHECK-NEXT: EndAddressOfRawData: 0x180007001
+// CHECK-NEXT: AddressOfIndex: 0x180005000
+// CHECK-NEXT: AddressOfCallBacks: 0x0
+// CHECK-NEXT: SizeOfZeroFill: 0x0
+// CHECK-NEXT: Characteristics [ (0x100000)
+// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES (0x100000)
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+
+#--- tls-aarch64.s
+ .section .defa64,"dr",discard,_tls_index
+ .globl _tls_index
+_tls_index:
+ .long 0
+
+ .section .tls,"dr",discard,_tls_start
+ .globl _tls_start
+_tls_start:
+ .byte 0
+
+ .section .tls$ZZZ,"dr",discard,_tls_end
+ .globl _tls_end
+_tls_end:
+ .byte 0
+
+ .section .defa64,"dr",discard,_tls_used
+ .globl _tls_used
+_tls_used:
+ .xword _tls_start
+ .xword _tls_end
+ .xword _tls_index
+ .xword 0
+ .xword 0
+
+#--- aarch64.s
+ .section .a64,"dr"
+ .rva _tls_index
+ .rva _tls_used
+ .rva _tls_start
+ .rva _tls_end
+
+#--- tls-arm64ec.s
+ .section .defec,"dr",discard,_tls_index
+ .globl _tls_index
+_tls_index:
+ .long 0
+
+ .section .tls,"dr",discard,_tls_start
+ .globl _tls_start
+_tls_start:
+ .byte 0
+
+ .section .tls$ZZZ,"dr",discard,_tls_end
+ .globl _tls_end
+_tls_end:
+ .byte 0
+
+ .section .defec,"dr",discard,_tls_used
+ .globl _tls_used
+_tls_used:
+ .xword _tls_start
+ .xword _tls_end
+ .xword _tls_index
+ .xword 0
+ .xword 0
+
+#--- arm64ec.s
+ .section .ec,"dr"
+ .rva _tls_index
+ .rva _tls_used
+ .rva _tls_start
+ .rva _tls_end
``````````
</details>
https://github.com/llvm/llvm-project/pull/213533
More information about the llvm-branch-commits
mailing list