1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: llc -filetype=obj %S/Inputs/global-ctor-dtor.ll -o %t.global-ctor-dtor.o
3
4target triple = "wasm32-unknown-unknown"
5
6define hidden void @func1() {
7entry:
8  ret void
9}
10
11define hidden void @func2() {
12entry:
13  ret void
14}
15
16define hidden void @func3() {
17entry:
18  ret void
19}
20
21define hidden void @func4() {
22entry:
23  ret void
24}
25
26declare hidden void @externCtor()
27declare hidden void @externDtor()
28declare hidden void @__wasm_call_ctors()
29
30define i32 @__cxa_atexit(i32 %func, i32 %arg, i32 %dso_handle) {
31  ret i32 0
32}
33
34define hidden void @_start() {
35entry:
36  call void @__wasm_call_ctors();
37  ret void
38}
39
40@llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [
41  { i32, void ()*, i8* } { i32 1001, void ()* @func1, i8* null },
42  { i32, void ()*, i8* } { i32 101, void ()* @func1, i8* null },
43  { i32, void ()*, i8* } { i32 101, void ()* @func2, i8* null },
44  { i32, void ()*, i8* } { i32 4000, void ()* @externCtor, i8* null }
45]
46
47@llvm.global_dtors = appending global [4 x { i32, void ()*, i8* }] [
48  { i32, void ()*, i8* } { i32 1001, void ()* @func3, i8* null },
49  { i32, void ()*, i8* } { i32 101, void ()* @func3, i8* null },
50  { i32, void ()*, i8* } { i32 101, void ()* @func4, i8* null },
51  { i32, void ()*, i8* } { i32 4000, void ()* @externDtor, i8* null }
52]
53
54; RUN: wasm-ld --allow-undefined %t.o %t.global-ctor-dtor.o -o %t.wasm
55; RUN: obj2yaml %t.wasm | FileCheck %s
56
57; CHECK:        - Type:            IMPORT
58; CHECK-NEXT:     Imports:
59; CHECK-NEXT:       - Module:          env
60; CHECK-NEXT:         Field:           externDtor
61; CHECK-NEXT:         Kind:            FUNCTION
62; CHECK-NEXT:         SigIndex:        0
63; CHECK-NEXT:       - Module:          env
64; CHECK-NEXT:         Field:           externCtor
65; CHECK-NEXT:         Kind:            FUNCTION
66; CHECK-NEXT:         SigIndex:        0
67; CHECK:        - Type:            ELEM
68; CHECK-NEXT:     Segments:
69; CHECK-NEXT:       - Offset:
70; CHECK-NEXT:           Opcode:          I32_CONST
71; CHECK-NEXT:           Value:           1
72; CHECK-NEXT:         Functions:       [ 9, 11, 13, 17, 19, 21 ]
73; CHECK-NEXT:   - Type:            CODE
74; CHECK-NEXT:     Functions:
75; CHECK-NEXT:       - Index:           2
76; CHECK-NEXT:         Locals:
77; CHECK-NEXT:         Body:            10031004100A100F1012100F10141003100C100F10161001100E0B
78; CHECK:            - Index:           22
79; CHECK-NEXT:         Locals:
80; CHECK-NEXT:         Body:            02404186808080004100418088808000108780808000450D0000000B0B
81; CHECK-NEXT:   - Type:            CUSTOM
82; CHECK-NEXT:     Name:            name
83; CHECK-NEXT:     FunctionNames:
84; CHECK-NEXT:       - Index:           0
85; CHECK-NEXT:         Name:            externDtor
86; CHECK-NEXT:       - Index:           1
87; CHECK-NEXT:         Name:            externCtor
88; CHECK-NEXT:       - Index:           2
89; CHECK-NEXT:         Name:            __wasm_call_ctors
90; CHECK-NEXT:       - Index:           3
91; CHECK-NEXT:         Name:            func1
92; CHECK-NEXT:       - Index:           4
93; CHECK-NEXT:         Name:            func2
94; CHECK-NEXT:       - Index:           5
95; CHECK-NEXT:         Name:            func3
96; CHECK-NEXT:       - Index:           6
97; CHECK-NEXT:         Name:            func4
98; CHECK-NEXT:       - Index:           7
99; CHECK-NEXT:         Name:            __cxa_atexit
100; CHECK-NEXT:       - Index:           8
101; CHECK-NEXT:         Name:            _start
102; CHECK-NEXT:       - Index:           9
103; CHECK-NEXT:         Name:            .Lcall_dtors.101
104; CHECK-NEXT:       - Index:           10
105; CHECK-NEXT:         Name:            .Lregister_call_dtors.101
106; CHECK-NEXT:       - Index:           11
107; CHECK-NEXT:         Name:            .Lcall_dtors.1001
108; CHECK-NEXT:       - Index:           12
109; CHECK-NEXT:         Name:            .Lregister_call_dtors.1001
110; CHECK-NEXT:       - Index:           13
111; CHECK-NEXT:         Name:            .Lcall_dtors.4000
112; CHECK-NEXT:       - Index:           14
113; CHECK-NEXT:         Name:            .Lregister_call_dtors.4000
114; CHECK-NEXT:       - Index:           15
115; CHECK-NEXT:         Name:            myctor
116; CHECK-NEXT:       - Index:           16
117; CHECK-NEXT:         Name:            mydtor
118; CHECK-NEXT:       - Index:           17
119; CHECK-NEXT:         Name:            .Lcall_dtors.101
120; CHECK-NEXT:       - Index:           18
121; CHECK-NEXT:         Name:            .Lregister_call_dtors.101
122; CHECK-NEXT:       - Index:           19
123; CHECK-NEXT:         Name:            .Lcall_dtors.202
124; CHECK-NEXT:       - Index:           20
125; CHECK-NEXT:         Name:            .Lregister_call_dtors.202
126; CHECK-NEXT:       - Index:           21
127; CHECK-NEXT:         Name:            .Lcall_dtors.2002
128; CHECK-NEXT:       - Index:           22
129; CHECK-NEXT:         Name:            .Lregister_call_dtors.2002
130; CHECK-NEXT:     GlobalNames:
131; CHECK-NEXT:       - Index:           0
132; CHECK-NEXT:         Name:            __stack_pointer
133; CHECK-NEXT: ...
134
135; RUN: wasm-ld -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm
136; RUN: llvm-readobj --symbols --sections %t.reloc.wasm | FileCheck -check-prefix=RELOC %s
137
138; RELOC:       Name: linking
139; RELOC-NEXT:  InitFunctions [
140; RELOC-NEXT:    0 (priority=101)
141; RELOC-NEXT:    1 (priority=101)
142; RELOC-NEXT:    14 (priority=101)
143; RELOC-NEXT:    10 (priority=101)
144; RELOC-NEXT:    20 (priority=101)
145; RELOC-NEXT:    10 (priority=202)
146; RELOC-NEXT:    22 (priority=202)
147; RELOC-NEXT:    0 (priority=1001)
148; RELOC-NEXT:    16 (priority=1001)
149; RELOC-NEXT:    10 (priority=2002)
150; RELOC-NEXT:    24 (priority=2002)
151; RELOC-NEXT:    9 (priority=4000)
152; RELOC-NEXT:    18 (priority=4000)
153; RELOC-NEXT:  ]
154