xref: /llvm-project-15.0.7/lld/test/wasm/pie.ll (revision 643dfd97)
1; RUN: llc -relocation-model=pic -mattr=+mutable-globals -filetype=obj %s -o %t.o
2; RUN: wasm-ld --no-gc-sections --experimental-pic -pie -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 DISASSEM
5
6target triple = "wasm32-unknown-emscripten"
7
8@data = global i32 2, align 4
9@data_external = external global i32
10@indirect_func = local_unnamed_addr global i32 ()* @foo, align 4
11
12@data_addr = local_unnamed_addr global i32* @data, align 4
13@data_addr_external = local_unnamed_addr global i32* @data_external, align 4
14
15define hidden i32 @foo() {
16entry:
17  ; To ensure we use __stack_pointer
18  %ptr = alloca i32
19  %0 = load i32, i32* @data, align 4
20  %1 = load i32 ()*, i32 ()** @indirect_func, align 4
21  call i32 %1()
22  ret i32 %0
23}
24
25define default i32** @get_data_address() {
26entry:
27  ret i32** @data_addr_external
28}
29
30define void @_start() {
31  call void @external_func()
32  ret void
33}
34
35declare void @external_func()
36
37; CHECK:      Sections:
38; CHECK-NEXT:   - Type:            CUSTOM
39; CHECK-NEXT:     Name:            dylink.0
40; CHECK-NEXT:     MemorySize:      16
41; CHECK-NEXT:     MemoryAlignment: 2
42; CHECK-NEXT:     TableSize:       1
43; CHECK-NEXT:     TableAlignment:  0
44; CHECK-NEXT:     Needed:          []
45
46; CHECK:        - Type:            IMPORT
47; CHECK-NEXT:     Imports:
48; CHECK-NEXT:      - Module:          env
49; CHECK-NEXT:        Field:           __indirect_function_table
50; CHECK-NEXT:        Kind:            TABLE
51; CHECK-NEXT:        Table:
52; CHECK-NEXT:          Index:           0
53; CHECK-NEXT:          ElemType:        FUNCREF
54; CHECK-NEXT:          Limits:
55; CHECK-NEXT:            Minimum:         0x1
56; CHECK-NEXT:       - Module:          env
57; CHECK-NEXT:         Field:           __stack_pointer
58; CHECK-NEXT:         Kind:            GLOBAL
59; CHECK-NEXT:         GlobalType:      I32
60; CHECK-NEXT:         GlobalMutable:   true
61; CHECK-NEXT:       - Module:          env
62; CHECK-NEXT:         Field:           __memory_base
63; CHECK-NEXT:         Kind:            GLOBAL
64; CHECK-NEXT:         GlobalType:      I32
65; CHECK-NEXT:         GlobalMutable:   false
66; CHECK-NEXT:       - Module:          env
67; CHECK-NEXT:         Field:           __table_base
68; CHECK-NEXT:         Kind:            GLOBAL
69; CHECK-NEXT:         GlobalType:      I32
70; CHECK-NEXT:         GlobalMutable:   false
71
72; CHECK:        - Type:            START
73; CHECK-NEXT:     StartFunction:   3
74
75; CHECK:        - Type:            CUSTOM
76; CHECK-NEXT:     Name:            name
77; CHECK-NEXT:     FunctionNames:
78; CHECK-NEXT:       - Index:           0
79; CHECK-NEXT:         Name:            external_func
80; CHECK-NEXT:       - Index:           1
81; CHECK-NEXT:         Name:            __wasm_call_ctors
82; CHECK-NEXT:       - Index:           2
83; CHECK-NEXT:         Name:            __wasm_apply_data_relocs
84; CHECK-NEXT:       - Index:           3
85; CHECK-NEXT:         Name:            __wasm_apply_global_relocs
86; CHECK-NEXT:       - Index:           4
87; CHECK-NEXT:         Name:            foo
88; CHECK-NEXT:       - Index:           5
89; CHECK-NEXT:         Name:            get_data_address
90; CHECK-NEXT:       - Index:           6
91; CHECK-NEXT:         Name:            _start
92; CHECK-NEXT:     GlobalNames:
93
94; DISASSEM-LABEL:  <__wasm_call_ctors>:
95; DISASSEM-EMPTY:
96; DISASSEM-NEXT:   end
97
98; DISASSEM-LABEL:  <__wasm_apply_data_relocs>:
99; DISASSEM:        end
100
101; Run the same test with extended-const support.  When this is available
102; we don't need __wasm_apply_global_relocs and instead rely on the add
103; instruction in the InitExpr.  We also, therefore, do not need these globals
104; to be mutable.
105
106; RUN: llc -relocation-model=pic -mattr=+extended-const,+mutable-globals,+atomics,+bulk-memory -filetype=obj %s -o %t.extended.o
107; RUN: wasm-ld --no-gc-sections --allow-undefined --experimental-pic -pie -o %t.extended.wasm %t.extended.o
108; RUN: obj2yaml %t.extended.wasm | FileCheck %s --check-prefix=EXTENDED-CONST
109
110; EXTENDED-CONST-NOT: __wasm_apply_global_relocs
111
112; EXTENDED-CONST:       - Type:            GLOBAL
113; EXTENDED-CONST-NEXT:    Globals:
114; EXTENDED-CONST-NEXT:      - Index:           4
115; EXTENDED-CONST-NEXT:        Type:            I32
116; EXTENDED-CONST-NEXT:        Mutable:         false
117; EXTENDED-CONST-NEXT:        InitExpr:
118; EXTENDED-CONST-NEXT:          Opcode:        GLOBAL_GET
119; EXTENDED-CONST-NEXT:          Index:         1
120; EXTENDED-CONST-NEXT:      - Index:           5
121; EXTENDED-CONST-NEXT:        Type:            I32
122; EXTENDED-CONST-NEXT:        Mutable:         false
123; EXTENDED-CONST-NEXT:        InitExpr:
124; EXTENDED-CONST-NEXT:          Extended:        true
125; EXTENDED-CONST-NEXT:          Body:            230141046A0B
126; EXTENDED-CONST-NEXT:      - Index:           6
127; EXTENDED-CONST-NEXT:        Type:            I32
128; EXTENDED-CONST-NEXT:        Mutable:         false
129; EXTENDED-CONST-NEXT:        InitExpr:
130; EXTENDED-CONST-NEXT:          Extended:        true
131; This instruction sequence decodes to:
132; (global.get[0x23] 0x1 i32.const[0x41] 0x0C i32.add[0x6A] end[0x0b])
133; EXTENDED-CONST-NEXT:          Body:            2301410C6A0B
134
135;  EXTENDED-CONST-NOT:  - Type:            START
136
137;      EXTENDED-CONST:    FunctionNames:
138; EXTENDED-CONST-NEXT:      - Index:           0
139; EXTENDED-CONST-NEXT:        Name:            external_func
140; EXTENDED-CONST-NEXT:      - Index:           1
141; EXTENDED-CONST-NEXT:        Name:            __wasm_call_ctors
142; EXTENDED-CONST-NEXT:      - Index:           2
143; EXTENDED-CONST-NEXT:        Name:            __wasm_apply_data_relocs
144
145; Run the same test with threading support.  In this mode
146; we expect __wasm_init_memory and __wasm_apply_data_relocs
147; to be generated along with __wasm_start as the start
148; function.
149
150; RUN: llc -relocation-model=pic -mattr=+mutable-globals,+atomics,+bulk-memory -filetype=obj %s -o %t.shmem.o
151; RUN: wasm-ld --no-gc-sections --shared-memory --allow-undefined --experimental-pic -pie -o %t.shmem.wasm %t.shmem.o
152; RUN: obj2yaml %t.shmem.wasm | FileCheck %s --check-prefix=SHMEM
153; RUN: llvm-objdump --disassemble-symbols=__wasm_start --no-show-raw-insn --no-leading-addr %t.shmem.wasm | FileCheck %s --check-prefix DISASSEM-SHMEM
154
155; SHMEM:         - Type:            START
156; SHMEM-NEXT:      StartFunction:   6
157
158; DISASSEM-SHMEM-LABEL:  <__wasm_start>:
159; DISASSEM-SHMEM-EMPTY:
160; DISASSEM-SHMEM-NEXT:   call 5
161; DISASSEM-SHMEM-NEXT:   call 4
162; DISASSEM-SHMEM-NEXT:   end
163
164; SHMEM:         FunctionNames:
165; SHMEM-NEXT:      - Index:           0
166; SHMEM-NEXT:        Name:            external_func
167; SHMEM-NEXT:      - Index:           1
168; SHMEM-NEXT:        Name:            __wasm_call_ctors
169; SHMEM-NEXT:      - Index:           2
170; SHMEM-NEXT:        Name:            __wasm_init_tls
171; SHMEM-NEXT:      - Index:           3
172; SHMEM-NEXT:        Name:            __wasm_apply_data_relocs
173; SHMEM-NEXT:      - Index:           4
174; SHMEM-NEXT:        Name:            __wasm_init_memory
175; SHMEM-NEXT:      - Index:           5
176; SHMEM-NEXT:        Name:            __wasm_apply_global_relocs
177; SHMEM-NEXT:      - Index:           6
178; SHMEM-NEXT:        Name:            __wasm_start
179; SHMEM-NEXT:      - Index:           7
180; SHMEM-NEXT:        Name:            foo
181; SHMEM-NEXT:      - Index:           8
182; SHMEM-NEXT:        Name:            get_data_address
183; SHMEM-NEXT:      - Index:           9
184; SHMEM-NEXT:        Name:            _start
185