xref: /llvm-project/lld/test/wasm/pie.s (revision 22b7b84860d39da71964c9b329937f2ee1d875ba)
1# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -o %t.o %s
2# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %S/Inputs/internal_func.s -o %t.internal_func.o
3# RUN: wasm-ld --no-gc-sections --experimental-pic -pie --unresolved-symbols=import-dynamic -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
6
7.functype external_func () -> ()
8.functype internal_func1 () -> (i32)
9.functype internal_func2 () -> (i32)
10.globaltype __stack_pointer, i32
11
12.section  .data,"",@
13.p2align  2
14data:
15  .int32  2
16  .size data, 4
17
18indirect_func:
19  .int32  foo
20  .size indirect_func, 4
21
22data_addr:
23  .int32  data
24  .size data_addr, 4
25
26data_addr_external:
27  .int32 data_external
28  .size data_addr_external, 4
29
30.section  .text,"",@
31foo:
32  .functype foo () -> (i32)
33
34  global.get data@GOT
35  i32.load 0
36  drop
37
38  global.get indirect_func@GOT
39  i32.load 0
40  call_indirect  () -> (i32)
41  drop
42
43  global.get __stack_pointer
44  end_function
45
46get_data_address:
47  .functype get_data_address () -> (i32)
48  global.get data_addr_external@GOT
49  end_function
50
51get_internal_func1_address:
52  .functype get_internal_func1_address () -> (i32)
53  global.get internal_func1@GOT
54  end_function
55
56get_internal_func2_address:
57  .functype get_internal_func2_address () -> (i32)
58  global.get internal_func2@GOT
59  end_function
60
61.globl _start
62_start:
63  .functype _start () -> ()
64  call external_func
65  end_function
66
67.section  .custom_section.target_features,"",@
68.int8 2
69.int8 43
70.int8 7
71.ascii  "atomics"
72.int8 43
73.int8 11
74.ascii  "bulk-memory"
75
76# CHECK:      Sections:
77# CHECK-NEXT:   - Type:            CUSTOM
78# CHECK-NEXT:     Name:            dylink.0
79# CHECK-NEXT:     MemorySize:      16
80# CHECK-NEXT:     MemoryAlignment: 2
81# CHECK-NEXT:     TableSize:       3
82# CHECK-NEXT:     TableAlignment:  0
83# CHECK-NEXT:     Needed:          []
84
85# CHECK:        - Type:            IMPORT
86# CHECK-NEXT:     Imports:
87# CHECK-NEXT:      - Module:          env
88# CHECK-NEXT:        Field:           __indirect_function_table
89# CHECK-NEXT:        Kind:            TABLE
90# CHECK-NEXT:        Table:
91# CHECK-NEXT:          Index:           0
92# CHECK-NEXT:          ElemType:        FUNCREF
93# CHECK-NEXT:          Limits:
94# CHECK-NEXT:            Minimum:         0x3
95# CHECK-NEXT:       - Module:          env
96# CHECK-NEXT:         Field:           __stack_pointer
97# CHECK-NEXT:         Kind:            GLOBAL
98# CHECK-NEXT:         GlobalType:      I32
99# CHECK-NEXT:         GlobalMutable:   true
100# CHECK-NEXT:       - Module:          env
101# CHECK-NEXT:         Field:           __memory_base
102# CHECK-NEXT:         Kind:            GLOBAL
103# CHECK-NEXT:         GlobalType:      I32
104# CHECK-NEXT:         GlobalMutable:   false
105# CHECK-NEXT:       - Module:          env
106# CHECK-NEXT:         Field:           __table_base
107# CHECK-NEXT:         Kind:            GLOBAL
108# CHECK-NEXT:         GlobalType:      I32
109# CHECK-NEXT:         GlobalMutable:   false
110
111# CHECK:        - Type:            START
112# CHECK-NEXT:     StartFunction:   3
113
114# CHECK:        - Type:            CUSTOM
115# CHECK-NEXT:     Name:            name
116# CHECK-NEXT:     FunctionNames:
117# CHECK-NEXT:       - Index:           0
118# CHECK-NEXT:         Name:            external_func
119# CHECK-NEXT:       - Index:           1
120# CHECK-NEXT:         Name:            __wasm_call_ctors
121# CHECK-NEXT:       - Index:           2
122# CHECK-NEXT:         Name:            __wasm_apply_data_relocs
123# CHECK-NEXT:       - Index:           3
124# CHECK-NEXT:         Name:            __wasm_apply_global_relocs
125# CHECK-NEXT:       - Index:           4
126# CHECK-NEXT:         Name:            foo
127# CHECK-NEXT:       - Index:           5
128# CHECK-NEXT:         Name:            get_data_address
129# CHECK-NEXT:       - Index:           6
130# CHECK-NEXT:         Name:            get_internal_func1_address
131# CHECK-NEXT:       - Index:           7
132# CHECK-NEXT:         Name:            get_internal_func2_address
133# CHECK-NEXT:       - Index:           8
134# CHECK-NEXT:         Name:            _start
135# CHECK-NEXT:       - Index:           9
136# CHECK-NEXT:         Name:            internal_func1
137# CHECK-NEXT:       - Index:           10
138# CHECK-NEXT:         Name:            internal_func2
139# CHECK-NEXT:     GlobalNames:
140
141# DISASSEM-LABEL:  <__wasm_call_ctors>:
142# DISASSEM-EMPTY:
143# DISASSEM-NEXT:   end
144
145# DISASSEM-LABEL:  <__wasm_apply_data_relocs>:
146# DISASSEM:        end
147
148# Run the same test with extended-const support.  When this is available
149# we don't need __wasm_apply_global_relocs and instead rely on the add
150# instruction in the InitExpr.  We also, therefore, do not need these globals
151# to be mutable.
152
153# RUN: wasm-ld --no-gc-sections --experimental-pic -pie --unresolved-symbols=import-dynamic --extra-features=extended-const -o %t.extended.wasm %t.o %t.internal_func.o
154# RUN: obj2yaml %t.extended.wasm | FileCheck %s --check-prefix=EXTENDED-CONST
155
156# EXTENDED-CONST-NOT: __wasm_apply_global_relocs
157
158# EXTENDED-CONST:       - Type:            GLOBAL
159# EXTENDED-CONST-NEXT:    Globals:
160# EXTENDED-CONST-NEXT:      - Index:           4
161# EXTENDED-CONST-NEXT:        Type:            I32
162# EXTENDED-CONST-NEXT:        Mutable:         false
163# EXTENDED-CONST-NEXT:        InitExpr:
164# EXTENDED-CONST-NEXT:          Opcode:        GLOBAL_GET
165# EXTENDED-CONST-NEXT:          Index:         1
166# EXTENDED-CONST-NEXT:      - Index:           5
167# EXTENDED-CONST-NEXT:        Type:            I32
168# EXTENDED-CONST-NEXT:        Mutable:         false
169# EXTENDED-CONST-NEXT:        InitExpr:
170# EXTENDED-CONST-NEXT:          Extended:        true
171# EXTENDED-CONST-NEXT:          Body:            230141046A0B
172# EXTENDED-CONST-NEXT:      - Index:           6
173# EXTENDED-CONST-NEXT:        Type:            I32
174# EXTENDED-CONST-NEXT:        Mutable:         false
175# EXTENDED-CONST-NEXT:        InitExpr:
176# EXTENDED-CONST-NEXT:          Extended:        true
177# This instruction sequence decodes to:
178# (global.get[0x23] 0x1 i32.const[0x41] 0x0C i32.add[0x6A] end[0x0b])
179# EXTENDED-CONST-NEXT:          Body:            2301410C6A0B
180# EXTENDED-CONST-NEXT:      - Index:           7
181# EXTENDED-CONST-NEXT:        Type:            I32
182# EXTENDED-CONST-NEXT:        Mutable:         false
183# EXTENDED-CONST-NEXT:        InitExpr:
184# EXTENDED-CONST-NEXT:          Opcode:        GLOBAL_GET
185# EXTENDED-CONST-NEXT:          Index:         2
186# EXTENDED-CONST-NEXT:      - Index:           8
187# EXTENDED-CONST-NEXT:        Type:            I32
188# EXTENDED-CONST-NEXT:        Mutable:         false
189# EXTENDED-CONST-NEXT:        InitExpr:
190# EXTENDED-CONST-NEXT:          Extended:        true
191# This instruction sequence decodes to:
192# (global.get[0x23] 0x2 i32.const[0x41] 0x1 i32.add[0x6A] end[0x0b])
193# EXTENDED-CONST-NEXT:          Body:            230241016A0B
194
195#  EXTENDED-CONST-NOT:  - Type:            START
196
197#      EXTENDED-CONST:    FunctionNames:
198# EXTENDED-CONST-NEXT:      - Index:           0
199# EXTENDED-CONST-NEXT:        Name:            external_func
200# EXTENDED-CONST-NEXT:      - Index:           1
201# EXTENDED-CONST-NEXT:        Name:            __wasm_call_ctors
202# EXTENDED-CONST-NEXT:      - Index:           2
203# EXTENDED-CONST-NEXT:        Name:            __wasm_apply_data_relocs
204
205# Run the same test with threading support.  In this mode
206# we expect __wasm_init_memory and __wasm_apply_data_relocs
207# to be generated along with __wasm_start as the start
208# function.
209
210# RUN: wasm-ld --no-gc-sections --shared-memory --experimental-pic -pie --unresolved-symbols=import-dynamic -o %t.shmem.wasm %t.o %t.internal_func.o
211# RUN: obj2yaml %t.shmem.wasm | FileCheck %s --check-prefix=SHMEM
212# RUN: llvm-objdump --disassemble-symbols=__wasm_start --no-show-raw-insn --no-leading-addr %t.shmem.wasm | FileCheck %s --check-prefix DISASSEM-SHMEM
213
214# SHMEM:         - Type:            START
215# SHMEM-NEXT:      StartFunction:   6
216
217# DISASSEM-SHMEM-LABEL:  <__wasm_start>:
218# DISASSEM-SHMEM-EMPTY:
219# DISASSEM-SHMEM-NEXT:   call 5
220# DISASSEM-SHMEM-NEXT:   call 4
221# DISASSEM-SHMEM-NEXT:   end
222
223# SHMEM:         FunctionNames:
224# SHMEM-NEXT:      - Index:           0
225# SHMEM-NEXT:        Name:            external_func
226# SHMEM-NEXT:      - Index:           1
227# SHMEM-NEXT:        Name:            __wasm_call_ctors
228# SHMEM-NEXT:      - Index:           2
229# SHMEM-NEXT:        Name:            __wasm_init_tls
230# SHMEM-NEXT:      - Index:           3
231# SHMEM-NEXT:        Name:            __wasm_apply_data_relocs
232# SHMEM-NEXT:      - Index:           4
233# SHMEM-NEXT:        Name:            __wasm_init_memory
234# SHMEM-NEXT:      - Index:           5
235# SHMEM-NEXT:        Name:            __wasm_apply_global_relocs
236# SHMEM-NEXT:      - Index:           6
237# SHMEM-NEXT:        Name:            __wasm_start
238# SHMEM-NEXT:      - Index:           7
239# SHMEM-NEXT:        Name:            foo
240# SHMEM-NEXT:      - Index:           8
241# SHMEM-NEXT:        Name:            get_data_address
242# SHMEM-NEXT:      - Index:           9
243# SHMEM-NEXT:        Name:            get_internal_func1_address
244# SHMEM-NEXT:      - Index:           10
245# SHMEM-NEXT:        Name:            get_internal_func2_address
246# SHMEM-NEXT:      - Index:           11
247# SHMEM-NEXT:        Name:            _start
248