[lld] [WebAssembly] Fix __init_tls_base global in coop threading (PR #208597)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 9 17:53:49 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
Author: Alex Crichton (alexcrichton)
<details>
<summary>Changes</summary>
This commit updates how `wasm-ld` initializes the `__init_tls_base`
global during module instantiation. Previously this global was left
entirely unmodified meaning that it was always 0. This change updates
the `__wasm_init_memory` function to set this global dynamically in PIC
mode based on the TLS address calculation, or in non-PIC mode the
generation of `__wasm_init_memory` correctly sets it to the desired TLS
address.
cc https://github.com/WebAssembly/wasi-libc/issues/819
> **Note**: this is currently built on https://github.com/llvm/llvm-project/pull/208332
---
Patch is 31.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/208597.diff
11 Files Affected:
- (modified) lld/test/wasm/compress-relocs.s (+6-6)
- (modified) lld/test/wasm/compress-relocs64.s (+6-6)
- (modified) lld/test/wasm/cooperative-threading.s (+142-11)
- (modified) lld/test/wasm/data-segments.ll (+24-24)
- (modified) lld/test/wasm/runtime-relocations-himem.s (+2-2)
- (modified) lld/test/wasm/tls-non-shared-memory.s (+7-7)
- (modified) lld/test/wasm/tls-relocations.s (+2-2)
- (modified) lld/wasm/Driver.cpp (+12-4)
- (modified) lld/wasm/InputChunks.cpp (+8-2)
- (modified) lld/wasm/OutputSections.cpp (+1-2)
- (modified) lld/wasm/Writer.cpp (+78-31)
``````````diff
diff --git a/lld/test/wasm/compress-relocs.s b/lld/test/wasm/compress-relocs.s
index 37f1b3b170ff7..e872b941416af 100644
--- a/lld/test/wasm/compress-relocs.s
+++ b/lld/test/wasm/compress-relocs.s
@@ -47,16 +47,16 @@ test_memory_and_indirect_call_relocs:
end_function
# CHECK: test_memory_and_indirect_call_relocs
-# CHECK: 41 90 80 84 80 00 i32.const 65552
+# CHECK: 41 80 80 84 80 00 i32.const 65536
# CHECK: 11 80 80 80 80 00 80 80 80 80 00 call_indirect 0
-# CHECK: 28 02 94 80 84 80 00 i32.load 65556
+# CHECK: 28 02 84 80 84 80 00 i32.load 65540
# CHECK: 11 81 80 80 80 00 80 80 80 80 00 call_indirect 1
# CHECK: 41 81 80 80 80 00 i32.const 1
# CHECK: 11 80 80 80 80 00 80 80 80 80 00 call_indirect 0
# COMPRESS: test_memory_and_indirect_call_relocs
-# COMPRESS: 41 90 80 04 i32.const 65552
+# COMPRESS: 41 80 80 04 i32.const 65536
# COMPRESS: 11 00 00 call_indirect 0
-# COMPRESS: 28 02 94 80 04 i32.load 65556
+# COMPRESS: 28 02 84 80 04 i32.load 65540
# COMPRESS: 11 01 00 call_indirect 1
# COMPRESS: 41 01 i32.const 1
# COMPRESS: 11 00 00 call_indirect 0
@@ -91,11 +91,11 @@ test_relative_relocs:
end_function
# CHECK: test_relative_relocs
-# CHECK: 41 90 80 84 80 00 i32.const 65552
+# CHECK: 41 80 80 84 80 00 i32.const 65536
# CHECK: 41 81 80 80 80 00 i32.const 1
# CHECK: 41 83 80 80 80 00 i32.const 3
# COMPRESS: test_relative_relocs
-# COMPRESS: 41 90 80 04 i32.const 65552
+# COMPRESS: 41 80 80 04 i32.const 65536
# COMPRESS: 41 01 i32.const 1
# COMPRESS: 41 03 i32.const 3
diff --git a/lld/test/wasm/compress-relocs64.s b/lld/test/wasm/compress-relocs64.s
index f3ff646cc3b1c..2dd18d604df41 100644
--- a/lld/test/wasm/compress-relocs64.s
+++ b/lld/test/wasm/compress-relocs64.s
@@ -36,12 +36,12 @@ test_memory_and_indirect_call_relocs:
end_function
# CHECK: test_memory_and_indirect_call_relocs
-# CHECK: 42 90 80 84 80 80 80 80 80 80 00 i64.const 65552
-# CHECK: 29 03 98 80 84 80 80 80 80 80 80 00 i64.load 65560
+# CHECK: 42 80 80 84 80 80 80 80 80 80 00 i64.const 65536
+# CHECK: 29 03 88 80 84 80 80 80 80 80 80 00 i64.load 65544
# CHECK: 42 81 80 80 80 80 80 80 80 80 00 i64.const 1
# COMPRESS: test_memory_and_indirect_call_relocs
-# COMPRESS: 42 90 80 04 i64.const 65552
-# COMPRESS: 29 03 98 80 04 i64.load 65560
+# COMPRESS: 42 80 80 04 i64.const 65536
+# COMPRESS: 29 03 88 80 04 i64.load 65544
# COMPRESS: 42 01 i64.const 1
.globl test_relative_relocs
@@ -56,11 +56,11 @@ test_relative_relocs:
end_function
# CHECK: test_relative_relocs
-# CHECK: 42 90 80 84 80 80 80 80 80 80 00 i64.const 65552
+# CHECK: 42 80 80 84 80 80 80 80 80 80 00 i64.const 65536
# CHECK: 42 81 80 80 80 80 80 80 80 80 00 i64.const 1
# CHECK: 42 83 80 80 80 80 80 80 80 80 00 i64.const 3
# COMPRESS: test_relative_relocs
-# COMPRESS: 42 90 80 04 i64.const 65552
+# COMPRESS: 42 80 80 04 i64.const 65536
# COMPRESS: 42 01 i64.const 1
# COMPRESS: 42 03 i64.const 3
diff --git a/lld/test/wasm/cooperative-threading.s b/lld/test/wasm/cooperative-threading.s
index 8b0f7eb1c256f..ffe5b524489fb 100644
--- a/lld/test/wasm/cooperative-threading.s
+++ b/lld/test/wasm/cooperative-threading.s
@@ -57,6 +57,13 @@ foo:
.int32 0
.size foo, 4
+.section .rodata.baz,"",@
+.globl baz
+.p2align 2
+baz:
+ .int32 1
+ .size baz, 4
+
.section .custom_section.target_features,"",@
.int8 2
.int8 43
@@ -72,22 +79,51 @@ foo:
# CHECK-NEXT: - Minimum: 0x2
# CHECK-NOT: Shared
-# Only TLS needs a passive data segment; .data stays active and .bss gets no
-# segment at all since memory is only instantiated once and starts zeroed.
+# Ensure __init_stack_pointer, __init_tls_base, and __tls_size are all correct.
+# CHECK: - Type: GLOBAL
+# CHECK-NEXT: Globals:
+# CHECK-NEXT: - Index: 0
+# CHECK-NEXT: Type: I32
+# CHECK-NEXT: Mutable: false
+# CHECK-NEXT: InitExpr:
+# CHECK-NEXT: Opcode: I32_CONST
+# CHECK-NEXT: Value: 65536
+# CHECK-NEXT: - Index: 1
+# CHECK-NEXT: Type: I32
+# CHECK-NEXT: Mutable: false
+# CHECK-NEXT: InitExpr:
+# CHECK-NEXT: Opcode: I32_CONST
+# CHECK-NEXT: Value: 65544
+# CHECK-NEXT: - Index: 2
+# CHECK-NEXT: Type: I32
+# CHECK-NEXT: Mutable: false
+# CHECK-NEXT: InitExpr:
+# CHECK-NEXT: Opcode: I32_CONST
+# CHECK-NEXT: Value: 8
+
+# Only TLS needs a passive data segment; .rodata and .data stay active and
+# .bss gets no segment at all since memory is only instantiated once and
+# starts zeroed. The TLS segment is sorted last.
# CHECK: - Type: DATACOUNT
-# CHECK-NEXT: Count: 2
+# CHECK-NEXT: Count: 3
# CHECK: - Type: DATA{{$}}
# CHECK-NEXT: Segments:
-# CHECK-NEXT: - SectionOffset: 3
-# CHECK-NEXT: InitFlags: 1
-# CHECK-NEXT: Content: '0100000002000000'
-# CHECK-NEXT: - SectionOffset: 18
+# CHECK-NEXT: - SectionOffset: 8
+# CHECK-NEXT: InitFlags: 0
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Opcode: I32_CONST
+# CHECK-NEXT: Value: 65536
+# CHECK-NEXT: Content: '01000000'
+# CHECK-NEXT: - SectionOffset: 19
# CHECK-NEXT: InitFlags: 0
# CHECK-NEXT: Offset:
# CHECK-NEXT: Opcode: I32_CONST
-# CHECK-NEXT: Value: {{[0-9]+}}
+# CHECK-NEXT: Value: 65540
# CHECK-NEXT: Content: 2A000000
+# CHECK-NEXT: - SectionOffset: 25
+# CHECK-NEXT: InitFlags: 1
+# CHECK-NEXT: Content: '0100000002000000'
# CHECK-NEXT: - Type: CUSTOM
# Globals should use the libcall ABI naming, not the global ABI.
@@ -102,9 +138,14 @@ foo:
# CHECK-NEXT: Name: __tls_align
# DIS-LABEL: <__wasm_init_memory>:
-# DIS: memory.init 0, 0
-# DIS-NOT: memory.fill
-# DIS-NOT: memory.init
+# DIS-EMPTY:
+# DIS-NEXT: i32.const 65544
+# DIS-NEXT: i32.const 65544
+# DIS-NEXT: call 0
+# DIS-NEXT: i32.const 0
+# DIS-NEXT: i32.const 8
+# DIS-NEXT: memory.init 2, 0
+# DIS-NEXT: end
# DIS-LABEL: <_start>:
# DIS-EMPTY:
@@ -118,3 +159,93 @@ foo:
# DIS-NEXT: i32.load 0
# DIS-NEXT: i32.add
# DIS-NEXT: end
+
+# Test --cooperative-threading combined with PIC output.
+# RUN: wasm-ld -shared --cooperative-threading -no-gc-sections -o %t.so %t.o
+# RUN: obj2yaml %t.so | FileCheck %s --check-prefix=PIC
+# RUN: llvm-objdump --disassemble-symbols=__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.so | FileCheck %s --check-prefix=PIC-DIS
+
+# The stack pointer is imported under the libcall ABI name and
+# __wasm_set_tls_base is imported for TLS initialization.
+# PIC: - Type: IMPORT
+# PIC: Field: __init_stack_pointer
+# PIC-NEXT: Kind: GLOBAL
+# PIC-NEXT: GlobalType: I32
+# PIC-NEXT: GlobalMutable: false
+# PIC: Field: __memory_base
+# PIC: Field: __table_base
+# PIC: Field: __wasm_set_tls_base
+# PIC-NEXT: Kind: FUNCTION
+
+# The PIC `__init_tls_base` global (global 3) is mutable and initialized ot
+# 0 since its final value is calculated once `__memory_base` is provided.
+# PIC: - Type: GLOBAL
+# PIC-NEXT: Globals:
+# PIC-NEXT: - Index: 3
+# PIC-NEXT: Type: I32
+# PIC-NEXT: Mutable: true
+# PIC-NEXT: InitExpr:
+# PIC-NEXT: Opcode: I32_CONST
+# PIC-NEXT: Value: 0
+# PIC-NEXT: - Index: 4
+# PIC-NEXT: Type: I32
+# PIC-NEXT: Mutable: false
+# PIC-NEXT: InitExpr:
+# PIC-NEXT: Opcode: I32_CONST
+# PIC-NEXT: Value: 8
+
+# In PIC mode the active .rodata and .data segments are combined into a single
+# active segment at __memory_base; the TLS segment remains passive.
+# PIC: - Type: DATACOUNT
+# PIC-NEXT: Count: 2
+# PIC: - Type: DATA{{$}}
+# PIC-NEXT: Segments:
+# PIC-NEXT: - SectionOffset: 6
+# PIC-NEXT: InitFlags: 0
+# PIC-NEXT: Offset:
+# PIC-NEXT: Opcode: GLOBAL_GET
+# PIC-NEXT: Index: {{[0-9]+}}
+# PIC-NEXT: Content: 010000002A000000
+# PIC-NEXT: - SectionOffset: {{[0-9]+}}
+# PIC-NEXT: InitFlags: 1
+# PIC-NEXT: Content: '0100000002000000'
+# PIC-NEXT: - Type: CUSTOM
+
+# PIC: GlobalNames:
+# PIC-NEXT: - Index: 0
+# PIC-NEXT: Name: __init_stack_pointer
+# PIC-NEXT: - Index: 1
+# PIC-NEXT: Name: __memory_base
+# PIC-NEXT: - Index: 2
+# PIC-NEXT: Name: __table_base
+# PIC-NEXT: - Index: 3
+# PIC-NEXT: Name: __init_tls_base
+# PIC-NEXT: - Index: 4
+# PIC-NEXT: Name: __tls_size
+# PIC-NEXT: - Index: 5
+# PIC-NEXT: Name: __tls_align
+
+# Memory initialization in PIC mode has a few responsibilities: it calculates
+# the TLS address and puts it in a local, stores it into the __init_tls_base
+# global, `__wasm_set_tls_base` is called, TLS is initialized, and then finally
+# BSS is zero'd out.
+# PIC-DIS: <__wasm_init_memory>:
+# PIC-DIS-NEXT: .local i32
+# PIC-DIS-NEXT: i32.const 8
+# PIC-DIS-NEXT: global.get 1
+# PIC-DIS-NEXT: i32.add
+# PIC-DIS-NEXT: local.tee 0
+# PIC-DIS-NEXT: global.set 3
+# PIC-DIS-NEXT: local.get 0
+# PIC-DIS-NEXT: call {{[0-9]+}}
+# PIC-DIS-NEXT: local.get 0
+# PIC-DIS-NEXT: i32.const 0
+# PIC-DIS-NEXT: i32.const 8
+# PIC-DIS-NEXT: memory.init 1, 0
+# PIC-DIS-NEXT: i32.const 16
+# PIC-DIS-NEXT: global.get {{[0-9]+}}
+# PIC-DIS-NEXT: i32.add
+# PIC-DIS-NEXT: i32.const 0
+# PIC-DIS-NEXT: i32.const 4
+# PIC-DIS-NEXT: memory.fill 0
+# PIC-DIS-NEXT: end
diff --git a/lld/test/wasm/data-segments.ll b/lld/test/wasm/data-segments.ll
index 7a18fd5efb655..5073e9c4cc8d1 100644
--- a/lld/test/wasm/data-segments.ll
+++ b/lld/test/wasm/data-segments.ll
@@ -93,7 +93,7 @@
; ACTIVE-PIC-NEXT: Offset:
; ACTIVE-PIC-NEXT: Opcode: GLOBAL_GET
; ACTIVE-PIC-NEXT: Index: 1
-; ACTIVE-PIC-NEXT: Content: 63000000636F6E7374616E74000000002B00000068656C6C6F00676F6F646279650000002A000000
+; ACTIVE-PIC-NEXT: Content: 636F6E7374616E74000000002B00000068656C6C6F00676F6F646279650000002A00000063000000
; PASSIVE-LABEL: - Type: START
; PASSIVE-NEXT: StartFunction: 2
@@ -114,13 +114,13 @@
; PASSIVE-NEXT: Segments:
; PASSIVE-NEXT: - SectionOffset: 3
; PASSIVE-NEXT: InitFlags: 1
-; PASSIVE-NEXT: Content: '63000000'
-; PASSIVE-NEXT: - SectionOffset: 9
-; PASSIVE-NEXT: InitFlags: 1
; PASSIVE-NEXT: Content: 636F6E7374616E74000000002B
-; PASSIVE-NEXT: - SectionOffset: 24
+; PASSIVE-NEXT: - SectionOffset: 18
; PASSIVE-NEXT: InitFlags: 1
; PASSIVE-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000
+; PASSIVE-NEXT: - SectionOffset: 40
+; PASSIVE-NEXT: InitFlags: 1
+; PASSIVE-NEXT: Content: '63000000'
; PASSIVE-NEXT: - Type: CUSTOM
; PASSIVE-NEXT: Name: name
; PASSIVE-NEXT: FunctionNames:
@@ -153,13 +153,13 @@
; PASSIVE-PIC-NEXT: Segments:
; PASSIVE-PIC-NEXT: - SectionOffset: 3
; PASSIVE-PIC-NEXT: InitFlags: 1
-; PASSIVE-PIC-NEXT: Content: '63000000'
-; PASSIVE-PIC-NEXT: - SectionOffset: 9
-; PASSIVE-PIC-NEXT: InitFlags: 1
; PASSIVE-PIC-NEXT: Content: 636F6E7374616E74000000002B
-; PASSIVE-PIC-NEXT: - SectionOffset: 24
+; PASSIVE-PIC-NEXT: - SectionOffset: 18
; PASSIVE-PIC-NEXT: InitFlags: 1
; PASSIVE-PIC-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000
+; PASSIVE-PIC-NEXT: - SectionOffset: 40
+; PASSIVE-PIC-NEXT: InitFlags: 1
+; PASSIVE-PIC-NEXT: Content: '63000000'
; PASSIVE-PIC-NEXT: - Type: CUSTOM
; PASSIVE-PIC-NEXT: Name: name
; PASSIVE-PIC-NEXT: FunctionNames:
@@ -212,34 +212,34 @@
; DIS-NEXT: end
; NOPIC-DIS-NEXT: [[PTR]].const 65536
-; NOPIC-DIS-NEXT: [[PTR]].const 65536
-; NOPIC-DIS-NEXT: global.set 1
; PIC-DIS-NEXT: [[PTR]].const 0
; PIC-DIS-NEXT: global.get 1
; PIC-DIS-NEXT: [[PTR]].add
-; PIC-DIS-NEXT: local.tee 1
-; PIC-DIS-NEXT: global.set {{\d*}}
-; PIC-DIS-NEXT: local.get 1
+
; DIS-NEXT: i32.const 0
-; DIS-NEXT: i32.const 4
-; DIS-NEXT: memory.init 0, 0
+; DIS-NEXT: i32.const 13
+; DIS-NEXT: memory.init 0, 0
-; NOPIC-DIS-NEXT: [[PTR]].const 65540
-; PIC-DIS-NEXT: [[PTR]].const 4
+; NOPIC-DIS-NEXT: [[PTR]].const 65552
+; PIC-DIS-NEXT: [[PTR]].const 16
; PIC-DIS-NEXT: global.get 1
; PIC-DIS-NEXT: [[PTR]].add
; DIS-NEXT: i32.const 0
-; DIS-NEXT: i32.const 13
+; DIS-NEXT: i32.const 20
; DIS-NEXT: memory.init 1, 0
-; NOPIC-DIS-NEXT: [[PTR]].const 65556
-; PIC-DIS-NEXT: [[PTR]].const 20
+; NOPIC-DIS-NEXT: [[PTR]].const 65572
+; NOPIC-DIS-NEXT: [[PTR]].const 65572
+; NOPIC-DIS-NEXT: global.set 1
+; PIC-DIS-NEXT: [[PTR]].const 36
; PIC-DIS-NEXT: global.get 1
; PIC-DIS-NEXT: [[PTR]].add
-
+; PIC-DIS-NEXT: local.tee 1
+; PIC-DIS-NEXT: global.set {{\d*}}
+; PIC-DIS-NEXT: local.get 1
; DIS-NEXT: i32.const 0
-; DIS-NEXT: i32.const 20
+; DIS-NEXT: i32.const 4
; DIS-NEXT: memory.init 2, 0
; NOPIC-DIS-NEXT: [[PTR]].const 65576
; PIC-DIS-NEXT: [[PTR]].const 40
@@ -272,6 +272,6 @@
; DIS-NEXT: memory.atomic.wait32 0
; DIS-NEXT: drop
; DIS-NEXT: end
+; DIS-NEXT: data.drop 0
; DIS-NEXT: data.drop 1
-; DIS-NEXT: data.drop 2
; DIS-NEXT: end
diff --git a/lld/test/wasm/runtime-relocations-himem.s b/lld/test/wasm/runtime-relocations-himem.s
index 2d39a204c7904..2026e62a5af86 100644
--- a/lld/test/wasm/runtime-relocations-himem.s
+++ b/lld/test/wasm/runtime-relocations-himem.s
@@ -47,14 +47,14 @@ data_sym:
# CHECK: <__wasm_apply_data_relocs>:
# CHECK-EMPTY:
-# CHECK-NEXT: i32.const -2147483636
+# CHECK-NEXT: i32.const -2147483644
# CHECK-NEXT: global.get 0
# CHECK-NEXT: i32.store 0
# CHECK-NEXT: end
# CHECK: <__wasm_apply_tls_relocs>:
# CHECK-EMPTY:
-# CHECK-NEXT: i32.const -2147483644
+# CHECK-NEXT: i32.const -2147483636
# CHECK-NEXT: global.get 0
# CHECK-NEXT: i32.store 0
# CHECK-NEXT: end
diff --git a/lld/test/wasm/tls-non-shared-memory.s b/lld/test/wasm/tls-non-shared-memory.s
index 0a87ade7efb2e..21082a5603e7f 100644
--- a/lld/test/wasm/tls-non-shared-memory.s
+++ b/lld/test/wasm/tls-non-shared-memory.s
@@ -70,14 +70,14 @@ tls1:
# CHECK-NEXT: Mutable: false
# CHECK-NEXT: InitExpr:
# CHECK-NEXT: Opcode: I32_CONST
-# CHECK-NEXT: Value: 65536
+# CHECK-NEXT: Value: 65540
# GOT.data.internal.tls1
# CHECK-NEXT: - Index: 2
# CHECK-NEXT: Type: I32
# CHECK-NEXT: Mutable: false
# CHECK-NEXT: InitExpr:
# CHECK-NEXT: Opcode: I32_CONST
-# CHECK-NEXT: Value: 65536
+# CHECK-NEXT: Value: 65540
# CHECK-NEXT: - Type: EXPORT
# CHECK: - Type: DATA
@@ -88,14 +88,14 @@ tls1:
# CHECK-NEXT: Offset:
# CHECK-NEXT: Opcode: I32_CONST
# CHECK-NEXT: Value: 65536
-# CHECK-NEXT: Content: 2B000000
+# CHECK-NEXT: Content: 2A000000
# .tdata
# CHECK-NEXT: - SectionOffset: 19
# CHECK-NEXT: InitFlags: 0
# CHECK-NEXT: Offset:
# CHECK-NEXT: Opcode: I32_CONST
# CHECK-NEXT: Value: 65540
-# CHECK-NEXT: Content: 2A000000
+# CHECK-NEXT: Content: 2B000000
# CHECK-NEXT: - Type: CUSTOM
# The constant value here which we add to `__tls_base` should not be absolute
@@ -146,7 +146,7 @@ tls1:
# PIC-NEXT: Offset:
# PIC-NEXT: Opcode: GLOBAL_GET
# PIC-NEXT: Index: {{\d*}}
-# PIC-NEXT: Content: 2B0000002A000000
+# PIC-NEXT: Content: 2A0000002B000000
# PIC-NEXT: - Type: CUSTOM
# Unless we have extended-const, in which case the merging is not needed.
@@ -160,7 +160,7 @@ tls1:
# EXT-CONST-NEXT: Offset:
# EXT-CONST-NEXT: Opcode: GLOBAL_GET
# EXT-CONST-NEXT: Index: 1
-# EXT-CONST-NEXT: Content: 2B000000
+# EXT-CONST-NEXT: Content: 2A000000
# EXT-CONST-NEXT: - SectionOffset: 18
# EXT-CONST-NEXT: InitFlags: 0
# EXT-CONST-NEXT: Offset:
@@ -168,4 +168,4 @@ tls1:
# This instruction sequence decodes to:
# (global.get[0x23] 0x1 i32.const[0x41] 0x04 i32.add[0x6A] end[0x0b])
# EXT-CONST-NEXT: Body: 230141046A0B
-# EXT-CONST-NEXT: Content: 2A000000
+# EXT-CONST-NEXT: Content: 2B000000
diff --git a/lld/test/wasm/tls-relocations.s b/lld/test/wasm/tls-relocations.s
index 9679074d6a0db..b5d1304177744 100644
--- a/lld/test/wasm/tls-relocations.s
+++ b/lld/test/wasm/tls-relocations.s
@@ -64,7 +64,7 @@ tls_sym:
# ASM-NEXT: local.get 0
# ASM-NEXT: i32.const 0
# ASM-NEXT: i32.const 16
-# ASM-NEXT: memory.init 0, 0
+# ASM-NEXT: memory.init 1, 0
# call to __wasm_apply_tls_relocs
# ASM-NEXT: call 3
# ASM-NEXT: end
@@ -75,7 +75,7 @@ tls_sym:
# ASM-NEXT: global.get 3
# ASM-NEXT: i32.add
# ASM-NEXT: global.get 1
-# ASM-NEXT: i32.const 20
+# ASM-NEXT: i32.const 4
# ASM-NEXT: i32.add
# ASM-NEXT: i32.store 0
# ASM-NEXT: i32.const 12
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 9a2e3a82a9279..00b6b1b3b5b2e 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -970,12 +970,20 @@ static void createSyntheticSymbols() {
}
if (ctx.arg.isMultithreaded()) {
- // TLS symbols are all hidden/dso-local
+ // TLS symbols are all hidden/dso-local, and note that the `tlsBase` global
+ // serves a different purpose depending on `libcallThreadContext`. If
+ // `libcallThreadContext` is `false` it's the base address of TLS and it's
+ // initialized fresh by each thread. This requires a mutable global.
+ //
+ // If `libca...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/208597
More information about the llvm-commits
mailing list