1 ; RUN: llc -relocation-model=pic -mattr=+mutable-globals -filetype=obj %s -o %t.o
2 ; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -filetype=obj %S/Inputs/internal_func.s -o %t.internal_func.o
3 ; RUN: wasm-ld --no-gc-sections --experimental-pic -pie -o %t.wasm %t.o %t.internal_func.o
4 ; RUN: obj2yaml %t.wasm | FileCheck %s
5 ; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DISASSEM
7 target triple = "wasm32-unknown-emscripten"
9 @data = global i32 2, align 4
10 @data_external = external global i32
11 @indirect_func = local_unnamed_addr global ptr @foo, align 4
13 @data_addr = local_unnamed_addr global ptr @data, align 4
14 @data_addr_external = local_unnamed_addr global ptr @data_external, align 4
16 define hidden i32 @foo() {
18 ; To ensure we use __stack_pointer
20 %0 = load i32, ptr @data, align 4
21 %1 = load ptr, ptr @indirect_func, align 4
26 define default ptr @get_data_address() {
28 ret ptr @data_addr_external
31 define default ptr @get_internal_func1_address() {
33 ret ptr @internal_func1
36 define default ptr @get_internal_func2_address() {
38 ret ptr @internal_func2
41 define void @_start() {
42 call void @external_func()
46 declare void @external_func()
47 declare ptr @internal_func1()
48 declare ptr @internal_func2()
51 ; CHECK-NEXT: - Type: CUSTOM
52 ; CHECK-NEXT: Name: dylink.0
53 ; CHECK-NEXT: MemorySize: 16
54 ; CHECK-NEXT: MemoryAlignment: 2
55 ; CHECK-NEXT: TableSize: 3
56 ; CHECK-NEXT: TableAlignment: 0
57 ; CHECK-NEXT: Needed: []
59 ; CHECK: - Type: IMPORT
60 ; CHECK-NEXT: Imports:
61 ; CHECK-NEXT: - Module: env
62 ; CHECK-NEXT: Field: __indirect_function_table
63 ; CHECK-NEXT: Kind: TABLE
65 ; CHECK-NEXT: Index: 0
66 ; CHECK-NEXT: ElemType: FUNCREF
68 ; CHECK-NEXT: Minimum: 0x3
69 ; CHECK-NEXT: - Module: env
70 ; CHECK-NEXT: Field: __stack_pointer
71 ; CHECK-NEXT: Kind: GLOBAL
72 ; CHECK-NEXT: GlobalType: I32
73 ; CHECK-NEXT: GlobalMutable: true
74 ; CHECK-NEXT: - Module: env
75 ; CHECK-NEXT: Field: __memory_base
76 ; CHECK-NEXT: Kind: GLOBAL
77 ; CHECK-NEXT: GlobalType: I32
78 ; CHECK-NEXT: GlobalMutable: false
79 ; CHECK-NEXT: - Module: env
80 ; CHECK-NEXT: Field: __table_base
81 ; CHECK-NEXT: Kind: GLOBAL
82 ; CHECK-NEXT: GlobalType: I32
83 ; CHECK-NEXT: GlobalMutable: false
85 ; CHECK: - Type: START
86 ; CHECK-NEXT: StartFunction: 3
88 ; CHECK: - Type: CUSTOM
89 ; CHECK-NEXT: Name: name
90 ; CHECK-NEXT: FunctionNames:
91 ; CHECK-NEXT: - Index: 0
92 ; CHECK-NEXT: Name: external_func
93 ; CHECK-NEXT: - Index: 1
94 ; CHECK-NEXT: Name: __wasm_call_ctors
95 ; CHECK-NEXT: - Index: 2
96 ; CHECK-NEXT: Name: __wasm_apply_data_relocs
97 ; CHECK-NEXT: - Index: 3
98 ; CHECK-NEXT: Name: __wasm_apply_global_relocs
99 ; CHECK-NEXT: - Index: 4
100 ; CHECK-NEXT: Name: foo
101 ; CHECK-NEXT: - Index: 5
102 ; CHECK-NEXT: Name: get_data_address
103 ; CHECK-NEXT: - Index: 6
104 ; CHECK-NEXT: Name: get_internal_func1_address
105 ; CHECK-NEXT: - Index: 7
106 ; CHECK-NEXT: Name: get_internal_func2_address
107 ; CHECK-NEXT: - Index: 8
108 ; CHECK-NEXT: Name: _start
109 ; CHECK-NEXT: - Index: 9
110 ; CHECK-NEXT: Name: internal_func1
111 ; CHECK-NEXT: - Index: 10
112 ; CHECK-NEXT: Name: internal_func2
113 ; CHECK-NEXT: GlobalNames:
115 ; DISASSEM-LABEL: <__wasm_call_ctors>:
119 ; DISASSEM-LABEL: <__wasm_apply_data_relocs>:
122 ; Run the same test with extended-const support. When this is available
123 ; we don't need __wasm_apply_global_relocs and instead rely on the add
124 ; instruction in the InitExpr. We also, therefore, do not need these globals
127 ; RUN: llc -relocation-model=pic -mattr=+extended-const,+mutable-globals,+atomics,+bulk-memory -filetype=obj %s -o %t.extended.o
128 ; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -filetype=obj %S/Inputs/internal_func.s -o %t.internal_func.extended.o
129 ; RUN: wasm-ld --no-gc-sections --experimental-pic -pie -o %t.extended.wasm %t.extended.o %t.internal_func.extended.o
130 ; RUN: obj2yaml %t.extended.wasm | FileCheck %s --check-prefix=EXTENDED-CONST
132 ; EXTENDED-CONST-NOT: __wasm_apply_global_relocs
134 ; EXTENDED-CONST: - Type: GLOBAL
135 ; EXTENDED-CONST-NEXT: Globals:
136 ; EXTENDED-CONST-NEXT: - Index: 4
137 ; EXTENDED-CONST-NEXT: Type: I32
138 ; EXTENDED-CONST-NEXT: Mutable: false
139 ; EXTENDED-CONST-NEXT: InitExpr:
140 ; EXTENDED-CONST-NEXT: Opcode: GLOBAL_GET
141 ; EXTENDED-CONST-NEXT: Index: 1
142 ; EXTENDED-CONST-NEXT: - Index: 5
143 ; EXTENDED-CONST-NEXT: Type: I32
144 ; EXTENDED-CONST-NEXT: Mutable: false
145 ; EXTENDED-CONST-NEXT: InitExpr:
146 ; EXTENDED-CONST-NEXT: Extended: true
147 ; EXTENDED-CONST-NEXT: Body: 230141046A0B
148 ; EXTENDED-CONST-NEXT: - Index: 6
149 ; EXTENDED-CONST-NEXT: Type: I32
150 ; EXTENDED-CONST-NEXT: Mutable: false
151 ; EXTENDED-CONST-NEXT: InitExpr:
152 ; EXTENDED-CONST-NEXT: Extended: true
153 ; This instruction sequence decodes to:
154 ; (global.get[0x23] 0x1 i32.const[0x41] 0x0C i32.add[0x6A] end[0x0b])
155 ; EXTENDED-CONST-NEXT: Body: 2301410C6A0B
156 ; EXTENDED-CONST-NEXT: - Index: 7
157 ; EXTENDED-CONST-NEXT: Type: I32
158 ; EXTENDED-CONST-NEXT: Mutable: false
159 ; EXTENDED-CONST-NEXT: InitExpr:
160 ; EXTENDED-CONST-NEXT: Opcode: GLOBAL_GET
161 ; EXTENDED-CONST-NEXT: Index: 2
162 ; EXTENDED-CONST-NEXT: - Index: 8
163 ; EXTENDED-CONST-NEXT: Type: I32
164 ; EXTENDED-CONST-NEXT: Mutable: false
165 ; EXTENDED-CONST-NEXT: InitExpr:
166 ; EXTENDED-CONST-NEXT: Extended: true
167 ; This instruction sequence decodes to:
168 ; (global.get[0x23] 0x2 i32.const[0x41] 0x1 i32.add[0x6A] end[0x0b])
169 ; EXTENDED-CONST-NEXT: Body: 230241016A0B
171 ; EXTENDED-CONST-NOT: - Type: START
173 ; EXTENDED-CONST: FunctionNames:
174 ; EXTENDED-CONST-NEXT: - Index: 0
175 ; EXTENDED-CONST-NEXT: Name: external_func
176 ; EXTENDED-CONST-NEXT: - Index: 1
177 ; EXTENDED-CONST-NEXT: Name: __wasm_call_ctors
178 ; EXTENDED-CONST-NEXT: - Index: 2
179 ; EXTENDED-CONST-NEXT: Name: __wasm_apply_data_relocs
181 ; Run the same test with threading support. In this mode
182 ; we expect __wasm_init_memory and __wasm_apply_data_relocs
183 ; to be generated along with __wasm_start as the start
186 ; RUN: llc -relocation-model=pic -mattr=+mutable-globals,+atomics,+bulk-memory -filetype=obj %s -o %t.shmem.o
187 ; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -filetype=obj %S/Inputs/internal_func.s -o %t.internal_func.shmem.o
188 ; RUN: wasm-ld --no-gc-sections --shared-memory --experimental-pic -pie -o %t.shmem.wasm %t.shmem.o %t.internal_func.shmem.o
189 ; RUN: obj2yaml %t.shmem.wasm | FileCheck %s --check-prefix=SHMEM
190 ; RUN: llvm-objdump --disassemble-symbols=__wasm_start --no-show-raw-insn --no-leading-addr %t.shmem.wasm | FileCheck %s --check-prefix DISASSEM-SHMEM
192 ; SHMEM: - Type: START
193 ; SHMEM-NEXT: StartFunction: 6
195 ; DISASSEM-SHMEM-LABEL: <__wasm_start>:
196 ; DISASSEM-SHMEM-EMPTY:
197 ; DISASSEM-SHMEM-NEXT: call 5
198 ; DISASSEM-SHMEM-NEXT: call 4
199 ; DISASSEM-SHMEM-NEXT: end
201 ; SHMEM: FunctionNames:
202 ; SHMEM-NEXT: - Index: 0
203 ; SHMEM-NEXT: Name: external_func
204 ; SHMEM-NEXT: - Index: 1
205 ; SHMEM-NEXT: Name: __wasm_call_ctors
206 ; SHMEM-NEXT: - Index: 2
207 ; SHMEM-NEXT: Name: __wasm_init_tls
208 ; SHMEM-NEXT: - Index: 3
209 ; SHMEM-NEXT: Name: __wasm_apply_data_relocs
210 ; SHMEM-NEXT: - Index: 4
211 ; SHMEM-NEXT: Name: __wasm_init_memory
212 ; SHMEM-NEXT: - Index: 5
213 ; SHMEM-NEXT: Name: __wasm_apply_global_relocs
214 ; SHMEM-NEXT: - Index: 6
215 ; SHMEM-NEXT: Name: __wasm_start
216 ; SHMEM-NEXT: - Index: 7
217 ; SHMEM-NEXT: Name: foo
218 ; SHMEM-NEXT: - Index: 8
219 ; SHMEM-NEXT: Name: get_data_address
220 ; SHMEM-NEXT: - Index: 9
221 ; SHMEM-NEXT: Name: get_internal_func1_address
222 ; SHMEM-NEXT: - Index: 10
223 ; SHMEM-NEXT: Name: get_internal_func2_address
224 ; SHMEM-NEXT: - Index: 11
225 ; SHMEM-NEXT: Name: _start