xref: /llvm-project/lld/test/wasm/tls-non-shared-memory.s (revision 1c1fbf51b5ec9657e5da7fa94ee892273255544a)
1# Test that linking without shared memory causes __tls_base to be
2# internalized.
3
4# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
5
6.globaltype __tls_base, i32
7
8.globl get_tls1
9get_tls1:
10  .functype get_tls1 () -> (i32)
11  global.get __tls_base
12  i32.const tls1@TLSREL
13  i32.add
14  end_function
15
16.globl get_tls1_got
17get_tls1_got:
18  .functype get_tls1_got () -> (i32)
19  global.get tls1@GOT@TLS
20  end_function
21
22.section  .data.no_tls,"",@
23.globl  no_tls
24.p2align  2
25no_tls:
26  .int32  42
27  .size no_tls, 4
28
29.section  .tdata.tls1,"T",@
30.globl  tls1
31.p2align  2
32tls1:
33  .int32  43
34  .size tls1, 2
35
36.section  .custom_section.target_features,"",@
37  .int8 2
38  .int8 43
39  .int8 7
40  .ascii  "atomics"
41  .int8 43
42  .int8 11
43  .ascii  "bulk-memory"
44
45# RUN: wasm-ld --no-gc-sections --no-entry -o %t.wasm %t.o
46# RUN: obj2yaml %t.wasm | FileCheck %s
47# RUN: llvm-objdump --disassemble-symbols=get_tls1 --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DIS
48
49# RUN: wasm-ld --experimental-pic -shared -o %t.so %t.o
50# RUN: obj2yaml %t.so | FileCheck %s --check-prefixes=SHARED,PIC
51
52# RUN: wasm-ld --experimental-pic --no-gc-sections --no-entry -pie -o %t-pie.wasm %t.o
53# RUN: obj2yaml %t-pie.wasm | FileCheck %s --check-prefixes=PIE,PIC
54
55# RUN: wasm-ld --experimental-pic --features=atomics,bulk-memory,extended-const --no-gc-sections --no-entry -pie -o %t-extended-const.wasm %t.o
56# RUN: obj2yaml %t-extended-const.wasm | FileCheck %s --check-prefixes=EXT-CONST
57
58#      CHECK:   - Type:            GLOBAL
59# __stack_pointer
60# CHECK-NEXT:     Globals:
61# CHECK-NEXT:       - Index:           0
62# CHECK-NEXT:         Type:            I32
63# CHECK-NEXT:         Mutable:         true
64# CHECK-NEXT:         InitExpr:
65# CHECK-NEXT:           Opcode:          I32_CONST
66# CHECK-NEXT:           Value:           66576
67# __tls_base
68# CHECK-NEXT:       - Index:           1
69# CHECK-NEXT:         Type:            I32
70# CHECK-NEXT:         Mutable:         false
71# CHECK-NEXT:         InitExpr:
72# CHECK-NEXT:           Opcode:          I32_CONST
73# CHECK-NEXT:           Value:           1024
74# GOT.data.internal.tls1
75# CHECK-NEXT:       - Index:           2
76# CHECK-NEXT:         Type:            I32
77# CHECK-NEXT:         Mutable:         false
78# CHECK-NEXT:         InitExpr:
79# CHECK-NEXT:           Opcode:          I32_CONST
80# CHECK-NEXT:           Value:           1024
81# CHECK-NEXT:   - Type:            EXPORT
82
83#      CHECK:  - Type:            DATA
84# .data
85# CHECK-NEXT:    Segments:
86# CHECK-NEXT:      - SectionOffset:   7
87# CHECK-NEXT:        InitFlags:       0
88# CHECK-NEXT:        Offset:
89# CHECK-NEXT:          Opcode:          I32_CONST
90# CHECK-NEXT:          Value:           1024
91# CHECK-NEXT:        Content:         2B000000
92# .tdata
93# CHECK-NEXT:      - SectionOffset:   17
94# CHECK-NEXT:        InitFlags:       0
95# CHECK-NEXT:        Offset:
96# CHECK-NEXT:          Opcode:          I32_CONST
97# CHECK-NEXT:          Value:           1028
98# CHECK-NEXT:        Content:         2A000000
99# CHECK-NEXT:  - Type:            CUSTOM
100
101# The constant value here which we add to `__tls_base` should not be absolute
102# but relative to `__tls_base`, in this case zero rather than 1024.
103# DIS:      <get_tls1>:
104# DIS-EMPTY:
105# DIS-NEXT:  global.get 1
106# DIS-NEXT:  i32.const 0
107# DIS-NEXT:  i32.add
108# DIS-NEXT:  end
109
110# In PIC mode we expect TLS data and non-TLS data to be merged into
111# a single segment which is initialized via the  __memory_base import
112
113#      SHARED:  - Type:            IMPORT
114# SHARED-NEXT:    Imports:
115# SHARED-NEXT:      - Module:          env
116# SHARED-NEXT:        Field:           memory
117# SHARED-NEXT:        Kind:            MEMORY
118# SHARED-NEXT:        Memory:
119# SHARED-NEXT:          Minimum:         0x1
120# SHARED-NEXT:      - Module:          env
121# SHARED-NEXT:        Field:           __memory_base
122# SHARED-NEXT:        Kind:            GLOBAL
123# SHARED-NEXT:        GlobalType:      I32
124
125# In SHARED mode we export the address of all data symbols.
126#      SHARED:   - Type:            EXPORT
127# SHARED-NEXT:     Exports:
128#      SHARED:     - Name:            tls1
129# SHARED-NEXT:       Kind:            GLOBAL
130#      SHARED:     - Name:            no_tls
131# SHARED-NEXT:       Kind:            GLOBAL
132
133# In PIE mode we don't export data address by default.
134#      PIE:   - Type:            EXPORT
135# PIE-NEXT:     Exports:
136# PIE-NEXT:       - Name:            memory
137# PIE-NEXT:         Kind:            MEMORY
138# PIE-NEXT:         Index:           0
139# PIE-NEXT:   - Type:
140
141# .tdata and .data are combined into single segment in PIC mode.
142#      PIC:  - Type:            DATA
143# PIC-NEXT:    Segments:
144# PIC-NEXT:      - SectionOffset:   6
145# PIC-NEXT:        InitFlags:       0
146# PIC-NEXT:        Offset:
147# PIC-NEXT:          Opcode:          GLOBAL_GET
148# PIC-NEXT:          Index:           {{\d*}}
149# PIC-NEXT:        Content:         2B0000002A000000
150# PIC-NEXT:  - Type:            CUSTOM
151
152# Unless we have extended-const, in which case the merging is not needed.
153# The first segment is placed directly at `__memory_base` and the second
154# one is offset from `__memory_base` using `i32.add` and a constant.
155
156#      EXT-CONST:  - Type:            DATA
157# EXT-CONST-NEXT:    Segments:
158# EXT-CONST-NEXT:      - SectionOffset:   6
159# EXT-CONST-NEXT:        InitFlags:       0
160# EXT-CONST-NEXT:        Offset:
161# EXT-CONST-NEXT:          Opcode:          GLOBAL_GET
162# EXT-CONST-NEXT:          Index:           1
163# EXT-CONST-NEXT:        Content:         2B000000
164# EXT-CONST-NEXT:      - SectionOffset:   18
165# EXT-CONST-NEXT:        InitFlags:       0
166# EXT-CONST-NEXT:        Offset:
167# EXT-CONST-NEXT:          Extended:        true
168# This instruction sequence decodes to:
169# (global.get[0x23] 0x1 i32.const[0x41] 0x04 i32.add[0x6A] end[0x0b])
170# EXT-CONST-NEXT:          Body:            230141046A0B
171# EXT-CONST-NEXT:        Content:         2A000000
172