[ELF] relocateNonAlloc: clean up workaround code
[llvm-project.git] / lld / test / wasm / shared.s
bloba26f00163fea70bb63b35f82a6129b963d8bbcd0
1 # RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
2 # RUN: wasm-ld --experimental-pic -shared -o %t.wasm %t.o
3 # RUN: obj2yaml %t.wasm | FileCheck %s
4 # 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 DIS
6 .functype func_external () -> ()
8 # Linker-synthesized globals
9 .globaltype __stack_pointer, i32
10 .globaltype __table_base, i32, immutable
11 .globaltype __memory_base, i32, immutable
13 .section .data.data,"",@
14 data:
15 .p2align 2
16 .int32 2
17 .size data, 4
19 .section .data.indirect_func_external,"",@
20 indirect_func_external:
21 .int32 func_external
22 .size indirect_func_external, 4
24 .section .data.indirect_func,"",@
25 indirect_func:
26 .int32 foo
27 .size indirect_func, 4
29 # Test data relocations
31 .section .data.data_addr,"",@
32 data_addr:
33 .int32 data
34 .size data_addr, 4
36 # .. against external symbols
38 .section .data.data_addr_external,"",@
39 data_addr_external:
40 .int32 data_external
41 .size data_addr_external, 4
43 # .. including addends
45 .section .data.extern_struct_internal_ptr,"",@
46 extern_struct_internal_ptr:
47 .int32 extern_struct + 4
48 .size extern_struct_internal_ptr, 4
50 # Test use of __stack_pointer
52 .section .text,"",@
53 foo:
54 # %ptr = alloca i32
55 # %0 = load i32, ptr @data, align 4
56 # %1 = load ptr, ptr @indirect_func, align 4
57 # call i32 %1()
58 # ret i32 %0
59 .functype foo () -> (i32)
60 .local i32, i32
61 global.get __stack_pointer
62 i32.const 16
63 i32.sub
64 local.tee 0
65 global.set __stack_pointer
66 global.get __memory_base
67 i32.const data@MBREL
68 i32.add
69 i32.load 0
70 local.set 1
71 global.get indirect_func@GOT
72 i32.load 0
73 call_indirect () -> (i32)
74 drop
75 local.get 0
76 i32.const 16
77 i32.add
78 global.set __stack_pointer
79 local.get 1
80 end_function
82 get_func_address:
83 .functype get_func_address () -> (i32)
84 global.get func_external@GOT
85 end_function
87 get_data_address:
88 .functype get_data_address () -> (i32)
89 global.get data_external@GOT
90 end_function
92 get_local_func_address:
93 # Verify that a function which is otherwise not address taken *is* added to
94 # the wasm table with referenced via R_WASM_TABLE_INDEX_REL_SLEB
95 .functype get_local_func_address () -> (i32)
96 global.get __table_base
97 i32.const get_func_address@TBREL
98 i32.add
99 end_function
101 .globl foo
102 .globl data
103 .globl indirect_func
104 .globl indirect_func_external
105 .globl data_addr
106 .globl data_addr_external
107 .globl extern_struct_internal_ptr
108 .globl get_data_address
109 .globl get_func_address
110 .globl get_local_func_address
112 .hidden foo
113 .hidden data
114 .hidden get_data_address
115 .hidden get_func_address
117 # Without this linking will fail because we import __stack_pointer (a mutable
118 # global).
119 # TODO(sbc): We probably want a nicer way to specify target_features section
120 # in assembly.
121 .section .custom_section.target_features,"",@
122 .int8 1
123 .int8 43
124 .int8 15
125 .ascii "mutable-globals"
127 # check for dylink section at start
129 # CHECK: Sections:
130 # CHECK-NEXT: - Type: CUSTOM
131 # CHECK-NEXT: Name: dylink.0
132 # CHECK-NEXT: MemorySize: 24
133 # CHECK-NEXT: MemoryAlignment: 2
134 # CHECK-NEXT: TableSize: 2
135 # CHECK-NEXT: TableAlignment: 0
136 # CHECK-NEXT: Needed: []
137 # CHECK-NEXT: - Type: TYPE
139 # check for import of __table_base and __memory_base globals
141 # CHECK: - Type: IMPORT
142 # CHECK-NEXT: Imports:
143 # CHECK-NEXT: - Module: env
144 # CHECK-NEXT: Field: memory
145 # CHECK-NEXT: Kind: MEMORY
146 # CHECK-NEXT: Memory:
147 # CHECK-NEXT: Minimum: 0x1
148 # CHECK-NEXT: - Module: env
149 # CHECK-NEXT: Field: __indirect_function_table
150 # CHECK-NEXT: Kind: TABLE
151 # CHECK-NEXT: Table:
152 # CHECK-NEXT: Index: 0
153 # CHECK-NEXT: ElemType: FUNCREF
154 # CHECK-NEXT: Limits:
155 # CHECK-NEXT: Minimum: 0x2
156 # CHECK-NEXT: - Module: env
157 # CHECK-NEXT: Field: __stack_pointer
158 # CHECK-NEXT: Kind: GLOBAL
159 # CHECK-NEXT: GlobalType: I32
160 # CHECK-NEXT: GlobalMutable: true
161 # CHECK-NEXT: - Module: env
162 # CHECK-NEXT: Field: __memory_base
163 # CHECK-NEXT: Kind: GLOBAL
164 # CHECK-NEXT: GlobalType: I32
165 # CHECK-NEXT: GlobalMutable: false
166 # CHECK-NEXT: - Module: env
167 # CHECK-NEXT: Field: __table_base
168 # CHECK-NEXT: Kind: GLOBAL
169 # CHECK-NEXT: GlobalType: I32
170 # CHECK-NEXT: GlobalMutable: false
171 # CHECK-NEXT: - Module: GOT.mem
172 # CHECK-NEXT: Field: indirect_func
173 # CHECK-NEXT: Kind: GLOBAL
174 # CHECK-NEXT: GlobalType: I32
175 # CHECK-NEXT: GlobalMutable: true
176 # CHECK-NEXT: - Module: GOT.func
177 # CHECK-NEXT: Field: func_external
178 # CHECK-NEXT: Kind: GLOBAL
179 # CHECK-NEXT: GlobalType: I32
180 # CHECK-NEXT: GlobalMutable: true
181 # CHECK-NEXT: - Module: GOT.mem
182 # CHECK-NEXT: Field: data_external
183 # CHECK-NEXT: Kind: GLOBAL
184 # CHECK-NEXT: GlobalType: I32
185 # CHECK-NEXT: GlobalMutable: true
186 # CHECK-NEXT: - Module: GOT.mem
187 # CHECK-NEXT: Field: extern_struct
188 # CHECK-NEXT: Kind: GLOBAL
189 # CHECK-NEXT: GlobalType: I32
190 # CHECK-NEXT: GlobalMutable: true
191 # CHECK-NEXT: - Type: FUNCTION
193 # CHECK: - Type: EXPORT
194 # CHECK-NEXT: Exports:
195 # CHECK-NEXT: - Name: __wasm_call_ctors
196 # CHECK-NEXT: Kind: FUNCTION
197 # CHECK-NEXT: Index: 0
199 # check for elem segment initialized with __table_base global as offset
201 # CHECK: - Type: ELEM
202 # CHECK-NEXT: Segments:
203 # CHECK-NEXT: - Offset:
204 # CHECK-NEXT: Opcode: GLOBAL_GET
205 # CHECK-NEXT: Index: 2
206 # CHECK-NEXT: Functions: [ 3, 2 ]
208 # check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions
210 # DIS: <__wasm_call_ctors>:
211 # DIS-EMPTY:
212 # DIS-NEXT: end
214 # DIS: <__wasm_apply_data_relocs>:
215 # DIS-EMPTY:
216 # DIS-NEXT: i32.const 4
217 # DIS-NEXT: global.get 1
218 # DIS-NEXT: i32.add
219 # DIS-NEXT: global.get 4
220 # DIS-NEXT: i32.store 0
221 # DIS-NEXT: i32.const 8
222 # DIS-NEXT: global.get 1
223 # DIS-NEXT: i32.add
224 # DIS-NEXT: global.get 2
225 # DIS-NEXT: i32.const 1
226 # DIS-NEXT: i32.add
227 # DIS-NEXT: i32.store 0
228 # DIS-NEXT: i32.const 12
229 # DIS-NEXT: global.get 1
230 # DIS-NEXT: i32.add
231 # DIS-NEXT: global.get 1
232 # DIS-NEXT: i32.const 0
233 # DIS-NEXT: i32.add
234 # DIS-NEXT: i32.store 0
235 # DIS-NEXT: i32.const 16
236 # DIS-NEXT: global.get 1
237 # DIS-NEXT: i32.add
238 # DIS-NEXT: global.get 5
239 # DIS-NEXT: i32.store 0
240 # DIS-NEXT: i32.const 20
241 # DIS-NEXT: global.get 1
242 # DIS-NEXT: i32.add
243 # DIS-NEXT: global.get 6
244 # DIS-NEXT: i32.const 4
245 # DIS-NEXT: i32.add
246 # DIS-NEXT: i32.store 0
247 # DIS-NEXT: end
249 # check the data segment initialized with __memory_base global as offset
251 # CHECK: - Type: DATA
252 # CHECK-NEXT: Segments:
253 # CHECK-NEXT: - SectionOffset: 6
254 # CHECK-NEXT: InitFlags: 0
255 # CHECK-NEXT: Offset:
256 # CHECK-NEXT: Opcode: GLOBAL_GET
257 # CHECK-NEXT: Index: 1
258 # CHECK-NEXT: Content: '020000000000000001000000000000000000000000000000'