1 // This test checks that we emit unwind info correctly for epilogs that
:
2 // 1. mirror the prolog; or
3 // 2. are subsequence at the end of the prolog; or
4 // 3. neither of above two.
5 // in the same segment.
6 // RUN
: llvm-mc
-triple aarch64-pc-win32
-filetype
=obj
%s
-o
%t.o
7 // RUN
: llvm-readobj
-S
-r
-u
%t.o | FileCheck
%s
11 // CHECK-NEXT
: Name
: .xdata (2E 78 64 61 74 61 00 00)
12 // CHECK-NEXT
: VirtualSize
: 0x0
13 // CHECK-NEXT
: VirtualAddress
: 0x0
14 // CHECK-NEXT
: RawDataSize
: 80
15 // CHECK-NEXT
: PointerToRawData
: 0x1251AC
16 // CHECK-NEXT
: PointerToRelocations
: 0x0
17 // CHECK-NEXT
: PointerToLineNumbers
: 0x0
18 // CHECK-NEXT
: RelocationCount
: 0
19 // CHECK-NEXT
: LineNumberCount
: 0
20 // CHECK-NEXT
: Characteristics
[ (0x40300040)
21 // CHECK-NEXT
: IMAGE_SCN_ALIGN_4BYTES
(0x300000)
22 // CHECK-NEXT
: IMAGE_SCN_CNT_INITIALIZED_DATA
(0x40)
23 // CHECK-NEXT
: IMAGE_SCN_MEM_READ
(0x40000000)
26 // CHECK-NEXT
: Section
{
27 // CHECK-NEXT
: Number
: 5
28 // CHECK-NEXT
: Name
: .pdata (2E 70 64 61 74 61 00 00)
29 // CHECK-NEXT
: VirtualSize
: 0x0
30 // CHECK-NEXT
: VirtualAddress
: 0x0
31 // CHECK-NEXT
: RawDataSize
: 16
32 // CHECK-NEXT
: PointerToRawData
: 0x1251FC
33 // CHECK-NEXT
: PointerToRelocations
: 0x12520C
34 // CHECK-NEXT
: PointerToLineNumbers
: 0x0
35 // CHECK-NEXT
: RelocationCount
: 4
36 // CHECK-NEXT
: LineNumberCount
: 0
37 // CHECK-NEXT
: Characteristics
[ (0x40300040)
38 // CHECK-NEXT
: IMAGE_SCN_ALIGN_4BYTES
(0x300000)
39 // CHECK-NEXT
: IMAGE_SCN_CNT_INITIALIZED_DATA
(0x40)
40 // CHECK-NEXT
: IMAGE_SCN_MEM_READ
(0x40000000)
44 // CHECK-LABEL
:Relocations
[
45 // CHECK-NEXT
: Section
(1) .text {
46 // CHECK-NEXT
: 0x94 IMAGE_REL_ARM64_BRANCH26 foo
(12)
47 // CHECK-NEXT
: 0x125068 IMAGE_REL_ARM64_BRANCH26 foo
(12)
49 // CHECK-NEXT
: Section
(5) .pdata {
50 // CHECK-NEXT
: 0x0 IMAGE_REL_ARM64_ADDR32NB
.text (0)
51 // CHECK-NEXT
: 0x4 IMAGE_REL_ARM64_ADDR32NB
.xdata (7)
52 // CHECK-NEXT
: 0x8 IMAGE_REL_ARM64_ADDR32NB
.text (0)
53 // CHECK-NEXT
: 0xC IMAGE_REL_ARM64_ADDR32NB
.xdata (7)
56 // CHECK-LABEL
:UnwindInformation
[
57 // CHECK-NEXT
: RuntimeFunction
{
58 // CHECK-NEXT
: Function
: multi_epilog
(0x0)
59 // CHECK-NEXT
: ExceptionRecord
: .xdata (0x0)
60 // CHECK-NEXT
: ExceptionData
{
61 // CHECK-NEXT
: FunctionLength
: 1048572
62 // CHECK-NEXT
: Version
: 0
63 // CHECK-NEXT
: ExceptionData
: No
64 // CHECK-NEXT
: EpiloguePacked
: No
65 // CHECK-NEXT
: EpilogueScopes
: 3
66 // CHECK-NEXT
: ByteCodeLength
: 24
67 // CHECK-NEXT
: Prologue
[
68 // CHECK-NEXT
: 0xe1 ; mov fp
, sp
69 // CHECK-NEXT
: 0xca16 ; stp x27
, x28
, [sp
, #176]
70 // CHECK-NEXT
: 0xc998 ; stp x25
, x26
, [sp
, #192]
71 // CHECK-NEXT
: 0xc91a ; stp x23
, x24
, [sp
, #208]
72 // CHECK-NEXT
: 0xc89c ; stp x21
, x22
, [sp
, #224]
73 // CHECK-NEXT
: 0xc81e ; stp x19
, x20
, [sp
, #240]
74 // CHECK-NEXT
: 0x9f ; stp x29
, x30
, [sp
, #-256]!
75 // CHECK-NEXT
: 0xe4 ; end
77 // CHECK-NEXT
: EpilogueScopes
[
78 // CHECK-NEXT
: EpilogueScope
{
79 // CHECK-NEXT
: StartOffset
: 38
80 // CHECK-NEXT
: EpilogueStartIndex
: 0
81 // CHECK-NEXT
: Opcodes
[
82 // CHECK-NEXT
: 0xe1 ; mov sp
, fp
83 // CHECK-NEXT
: 0xca16 ; ldp x27
, x28
, [sp
, #176]
84 // CHECK-NEXT
: 0xc998 ; ldp x25
, x26
, [sp
, #192]
85 // CHECK-NEXT
: 0xc91a ; ldp x23
, x24
, [sp
, #208]
86 // CHECK-NEXT
: 0xc89c ; ldp x21
, x22
, [sp
, #224]
87 // CHECK-NEXT
: 0xc81e ; ldp x19
, x20
, [sp
, #240]
88 // CHECK-NEXT
: 0x9f ; ldp x29
, x30
, [sp
], #256
89 // CHECK-NEXT
: 0xe4 ; end
92 // CHECK-NEXT
: EpilogueScope
{
93 // CHECK-NEXT
: StartOffset
: 46
94 // CHECK-NEXT
: EpilogueStartIndex
: 3
95 // CHECK-NEXT
: Opcodes
[
96 // CHECK-NEXT
: 0xc998 ; ldp x25
, x26
, [sp
, #192]
97 // CHECK-NEXT
: 0xc91a ; ldp x23
, x24
, [sp
, #208]
98 // CHECK-NEXT
: 0xc89c ; ldp x21
, x22
, [sp
, #224]
99 // CHECK-NEXT
: 0xc81e ; ldp x19
, x20
, [sp
, #240]
100 // CHECK-NEXT
: 0x9f ; ldp x29
, x30
, [sp
], #256
101 // CHECK-NEXT
: 0xe4 ; end
104 // CHECK-NEXT
: EpilogueScope
{
105 // CHECK-NEXT
: StartOffset
: 52
106 // CHECK-NEXT
: EpilogueStartIndex
: 13
107 // CHECK-NEXT
: Opcodes
[
108 // CHECK-NEXT
: 0xe1 ; mov sp
, fp
109 // CHECK-NEXT
: 0xc91a ; ldp x23
, x24
, [sp
, #208]
110 // CHECK-NEXT
: 0xc89c ; ldp x21
, x22
, [sp
, #224]
111 // CHECK-NEXT
: 0xc81e ; ldp x19
, x20
, [sp
, #240]
112 // CHECK-NEXT
: 0x9f ; ldp x29
, x30
, [sp
], #256
113 // CHECK-NEXT
: 0xe4 ; end
119 // CHECK-NEXT
: RuntimeFunction
{
120 // CHECK-NEXT
: Function
: multi_epilog
+0xFFFFC (0xFFFFC)
121 // CHECK-NEXT
: ExceptionRecord
: .xdata +0x28 (0x28)
122 // CHECK-NEXT
: ExceptionData
{
123 // CHECK-NEXT
: FunctionLength
: 151744
124 // CHECK-NEXT
: Version
: 0
125 // CHECK-NEXT
: ExceptionData
: No
126 // CHECK-NEXT
: EpiloguePacked
: No
127 // CHECK-NEXT
: EpilogueScopes
: 3
128 // CHECK-NEXT
: ByteCodeLength
: 24
129 // CHECK-NEXT
: Prologue
[
130 // CHECK-NEXT
: 0xe5 ; end_c
131 // CHECK-NEXT
: 0xe1 ; mov fp
, sp
132 // CHECK-NEXT
: 0xca16 ; stp x27
, x28
, [sp
, #176]
133 // CHECK-NEXT
: 0xc998 ; stp x25
, x26
, [sp
, #192]
134 // CHECK-NEXT
: 0xc91a ; stp x23
, x24
, [sp
, #208]
135 // CHECK-NEXT
: 0xc89c ; stp x21
, x22
, [sp
, #224]
136 // CHECK-NEXT
: 0xc81e ; stp x19
, x20
, [sp
, #240]
137 // CHECK-NEXT
: 0x9f ; stp x29
, x30
, [sp
, #-256]!
138 // CHECK-NEXT
: 0xe4 ; end
140 // CHECK-NEXT
: EpilogueScopes
[
141 // CHECK-NEXT
: EpilogueScope
{
142 // CHECK-NEXT
: StartOffset
: 37916
143 // CHECK-NEXT
: EpilogueStartIndex
: 1
144 // CHECK-NEXT
: Opcodes
[
145 // CHECK-NEXT
: 0xe1 ; mov sp
, fp
146 // CHECK-NEXT
: 0xca16 ; ldp x27
, x28
, [sp
, #176]
147 // CHECK-NEXT
: 0xc998 ; ldp x25
, x26
, [sp
, #192]
148 // CHECK-NEXT
: 0xc91a ; ldp x23
, x24
, [sp
, #208]
149 // CHECK-NEXT
: 0xc89c ; ldp x21
, x22
, [sp
, #224]
150 // CHECK-NEXT
: 0xc81e ; ldp x19
, x20
, [sp
, #240]
151 // CHECK-NEXT
: 0x9f ; ldp x29
, x30
, [sp
], #256
152 // CHECK-NEXT
: 0xe4 ; end
155 // CHECK-NEXT
: EpilogueScope
{
156 // CHECK-NEXT
: StartOffset
: 37924
157 // CHECK-NEXT
: EpilogueStartIndex
: 4
158 // CHECK-NEXT
: Opcodes
[
159 // CHECK-NEXT
: 0xc998 ; ldp x25
, x26
, [sp
, #192]
160 // CHECK-NEXT
: 0xc91a ; ldp x23
, x24
, [sp
, #208]
161 // CHECK-NEXT
: 0xc89c ; ldp x21
, x22
, [sp
, #224]
162 // CHECK-NEXT
: 0xc81e ; ldp x19
, x20
, [sp
, #240]
163 // CHECK-NEXT
: 0x9f ; ldp x29
, x30
, [sp
], #256
164 // CHECK-NEXT
: 0xe4 ; end
167 // CHECK-NEXT
: EpilogueScope
{
168 // CHECK-NEXT
: StartOffset
: 37930
169 // CHECK-NEXT
: EpilogueStartIndex
: 14
170 // CHECK-NEXT
: Opcodes
[
171 // CHECK-NEXT
: 0xe1 ; mov sp
, fp
172 // CHECK-NEXT
: 0xc91a ; ldp x23
, x24
, [sp
, #208]
173 // CHECK-NEXT
: 0xc89c ; ldp x21
, x22
, [sp
, #224]
174 // CHECK-NEXT
: 0xc81e ; ldp x19
, x20
, [sp
, #240]
175 // CHECK-NEXT
: 0x9f ; ldp x29
, x30
, [sp
], #256
176 // CHECK-NEXT
: 0xe4 ; end
187 .seh_proc multi_epilog
189 stp x29
, lr, [sp
, #-256]!
191 stp x19
, x20
, [sp
, #240]
192 .seh_save_regp x19, 240
193 stp x21
, x22
, [sp
, #224]
194 .seh_save_regp x21, 224
195 stp x23
, x24
, [sp
, #208]
196 .seh_save_regp x23, 208
197 stp x25
, x26
, [sp
, #192]
198 .seh_save_regp x25, 192
199 stp x27
, x28
, [sp
, #176]
200 .seh_save_regp x27, 176
208 // Epilogs
1, 2 and 3 are in the same segment as prolog.
209 // epilog1
- mirroring prolog
213 stp x27
, x28
, [sp
, #176]
214 .seh_save_regp x27, 176
215 stp x25
, x26
, [sp
, #192]
216 .seh_save_regp x25, 192
217 stp x23
, x24
, [sp
, #208]
218 .seh_save_regp x23, 208
219 stp x21
, x22
, [sp
, #224]
220 .seh_save_regp x21, 224
221 ldp x19
, x20
, [sp
, #240]
222 .seh_save_regp x19, 240
223 ldp x29
, lr, [sp
], #256
227 // epilog2
- a subsequence at the end of prolog
, can use prolog
's opcodes.
229 stp x25, x26, [sp, #192]
230 .seh_save_regp x25, 192
231 stp x23, x24, [sp, #208]
232 .seh_save_regp x23, 208
233 stp x21, x22, [sp, #224]
234 .seh_save_regp x21, 224
235 ldp x19, x20, [sp, #240]
236 .seh_save_regp x19, 240
237 ldp x29, lr, [sp], #256
241 // epilog3 - cannot use prolog's opcode.
245 stp x23
, x24
, [sp
, #208]
246 .seh_save_regp x23, 208
247 stp x21
, x22
, [sp
, #224]
248 .seh_save_regp x21, 224
249 ldp x19
, x20
, [sp
, #240]
250 .seh_save_regp x19, 240
251 ldp x29
, lr, [sp
], #256
259 // Epilogs below are in
a segment without prolog
260 // epilog4
- mirroring prolog
, its start index should
be 1, counting the end_c.
264 stp x27
, x28
, [sp
, #176]
265 .seh_save_regp x27, 176
266 stp x25
, x26
, [sp
, #192]
267 .seh_save_regp x25, 192
268 stp x23
, x24
, [sp
, #208]
269 .seh_save_regp x23, 208
270 stp x21
, x22
, [sp
, #224]
271 .seh_save_regp x21, 224
272 ldp x19
, x20
, [sp
, #240]
273 .seh_save_regp x19, 240
274 ldp x29
, lr, [sp
], #256
278 // epilog5
- same as epilog2
, its start index should
be: 1 + epilog2
's index.
280 stp x25, x26, [sp, #192]
281 .seh_save_regp x25, 192
282 stp x23, x24, [sp, #208]
283 .seh_save_regp x23, 208
284 stp x21, x22, [sp, #224]
285 .seh_save_regp x21, 224
286 ldp x19, x20, [sp, #240]
287 .seh_save_regp x19, 240
288 ldp x29, lr, [sp], #256
292 // epilog6 - same as epilog3, cannot use prolog's opcode. Again its start index
293 // should
be: 1 + epilog3
's index.
297 stp x23, x24, [sp, #208]
298 .seh_save_regp x23, 208
299 stp x21, x22, [sp, #224]
300 .seh_save_regp x21, 224
301 ldp x19, x20, [sp, #240]
302 .seh_save_regp x19, 240
303 ldp x29, lr, [sp], #256