xref: /llvm-project/llvm/test/MC/AArch64/seh.s (revision 825e4ae732f8e61fe69614005346a99ab2b67902)
1// This test checks that the SEH directives emit the correct unwind data.
2
3// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s | llvm-readobj -S -r -u - | FileCheck %s
4
5// Check that the output assembler directives also can be parsed, and
6// that they produce equivalent output:
7
8// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=asm %s | llvm-mc -triple aarch64-pc-win32 -filetype=obj - | llvm-readobj -S -r -u - | FileCheck %s
9
10// CHECK:      Sections [
11// CHECK:        Section {
12// CHECK:          Name: .text
13// CHECK:          RelocationCount: 0
14// CHECK:          Characteristics [
15// CHECK-NEXT:       ALIGN_4BYTES
16// CHECK-NEXT:       CNT_CODE
17// CHECK-NEXT:       MEM_EXECUTE
18// CHECK-NEXT:       MEM_READ
19// CHECK-NEXT:     ]
20// CHECK-NEXT:   }
21// CHECK:        Section {
22// CHECK:          Name: .xdata
23// CHECK:          RawDataSize: 92
24// CHECK:          RelocationCount: 1
25// CHECK:          Characteristics [
26// CHECK-NEXT:       ALIGN_4BYTES
27// CHECK-NEXT:       CNT_INITIALIZED_DATA
28// CHECK-NEXT:       MEM_READ
29// CHECK-NEXT:     ]
30// CHECK-NEXT:   }
31// CHECK:        Section {
32// CHECK:          Name: .pdata
33// CHECK:          RelocationCount: 2
34// CHECK:          Characteristics [
35// CHECK-NEXT:       ALIGN_4BYTES
36// CHECK-NEXT:       CNT_INITIALIZED_DATA
37// CHECK-NEXT:       MEM_READ
38// CHECK-NEXT:     ]
39// CHECK-NEXT:   }
40// CHECK-NEXT: ]
41
42// CHECK-NEXT: Relocations [
43// CHECK-NEXT:   Section (4) .xdata {
44// CHECK-NEXT:     0x50 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
45// CHECK-NEXT:   }
46// CHECK-NEXT:   Section (5) .pdata {
47// CHECK-NEXT:     0x0 IMAGE_REL_ARM64_ADDR32NB .text
48// CHECK-NEXT:     0x4 IMAGE_REL_ARM64_ADDR32NB .xdata
49// CHECK-NEXT:   }
50// CHECK-NEXT: ]
51
52// CHECK-NEXT: UnwindInformation [
53// CHECK-NEXT:   RuntimeFunction {
54// CHECK-NEXT:     Function: func
55// CHECK-NEXT:     ExceptionRecord: .xdata
56// CHECK-NEXT:     ExceptionData {
57// CHECK-NEXT:       FunctionLength: 156
58// CHECK:            Prologue [
59// CHECK-NEXT:         0xe76983            ; stp q9, q10, [sp, #-64]!
60// CHECK-NEXT:         0xe73d83            ; str q29, [sp, #-64]!
61// CHECK-NEXT:         0xe76243            ; stp d2, d3, [sp, #-64]!
62// CHECK-NEXT:         0xe73f43            ; str d31, [sp, #-64]!
63// CHECK-NEXT:         0xe77d03            ; stp x29, x30, [sp, #-64]!
64// CHECK-NEXT:         0xe73e03            ; str x30, [sp, #-64]!
65// CHECK-NEXT:         0xe74384            ; stp q3, q4, [sp, #64]
66// CHECK-NEXT:         0xe71e84            ; str q30, [sp, #64]
67// CHECK-NEXT:         0xe74444            ; stp d4, d5, [sp, #64]
68// CHECK-NEXT:         0xe71d48            ; str d29, [sp, #64]
69// CHECK-NEXT:         0xe74104            ; stp x1, x2, [sp, #64]
70// CHECK-NEXT:         0xe70008            ; str x0, [sp, #64]
71// CHECK-NEXT:         0xfc                ; pacibsp
72// CHECK-NEXT:         0xec                ; clear unwound to call
73// CHECK-NEXT:         0xeb                ; EC context
74// CHECK-NEXT:         0xea                ; context
75// CHECK-NEXT:         0xe9                ; machine frame
76// CHECK-NEXT:         0xe8                ; trap frame
77// CHECK-NEXT:         0xe3                ; nop
78// CHECK-NEXT:         0xe202              ; add fp, sp, #16
79// CHECK-NEXT:         0xdd41              ; str d13, [sp, #8]
80// CHECK-NEXT:         0xde83              ; str d12, [sp, #-32]!
81// CHECK-NEXT:         0xd884              ; stp d10, d11, [sp, #32]
82// CHECK-NEXT:         0xda05              ; stp d8, d9, [sp, #-48]!
83// CHECK-NEXT:         0x83                ; stp x29, x30, [sp, #-32]!
84// CHECK-NEXT:         0x46                ; stp x29, x30, [sp, #48]
85// CHECK-NEXT:         0xd141              ; str x24, [sp, #8]
86// CHECK-NEXT:         0xd483              ; str x23, [sp, #-32]!
87// CHECK-NEXT:         0xe6                ; save next
88// CHECK-NEXT:         0xc882              ; stp x21, x22, [sp, #16]
89// CHECK-NEXT:         0xd6c2              ; stp x25, lr, [sp, #16]
90// CHECK-NEXT:         0x24                ; stp x19, x20, [sp, #-32]!
91// CHECK-NEXT:         0xcc83              ; stp x21, x22, [sp, #-32]!
92// CHECK-NEXT:         0x83                ; stp x29, x30, [sp, #-32]!
93// CHECK-NEXT:         0xe1                ; mov fp, sp
94// CHECK-NEXT:         0x01                ; sub sp, #16
95// CHECK-NEXT:         0xe4                ; end
96// CHECK-NEXT:       ]
97// CHECK-NEXT:       EpilogueScopes [
98// CHECK-NEXT:         EpilogueScope {
99// CHECK-NEXT:           StartOffset: 37
100// CHECK-NEXT:           EpilogueStartIndex: 69
101// CHECK-NEXT:           Opcodes [
102// CHECK-NEXT:             0x01                ; add sp, #16
103// CHECK-NEXT:             0xe4                ; end
104// CHECK-NEXT:           ]
105// CHECK-NEXT:         }
106// CHECK-NEXT:       ]
107// CHECK-NEXT:       ExceptionHandler [
108// CHECK-NEXT:         Routine: __C_specific_handler (0x0)
109// CHECK-NEXT:         Parameter: 0x0
110// CHECK-NEXT:       ]
111// CHECK-NEXT:     }
112// CHECK-NEXT:   }
113// CHECK-NEXT: ]
114
115
116    .text
117    .globl func
118    .def func
119    .scl 2
120    .type 32
121    .endef
122    .seh_proc func
123func:
124    sub sp, sp, #24
125    .seh_stackalloc 24
126    mov x29, sp
127    .seh_set_fp
128    stp x29, x30, [sp, #-32]!
129    .seh_save_fplr_x 32
130    stp x21, x22, [sp, #-32]!
131    .seh_save_regp_x x21, 32
132    stp x19, x20, [sp, #-32]!
133    .seh_save_r19r20_x 32
134    stp x25, x30, [sp, #16]
135    .seh_save_lrpair x25, 16
136    stp x21, x22, [sp, #16]
137    .seh_save_regp x21, 16
138    stp x23, x24, [sp, #32]
139    .seh_save_next
140    str x23, [sp, #-32]!
141    .seh_save_reg_x x23, 32
142    str x24, [sp, #8]
143    .seh_save_reg x24, 8
144    stp x29, x30, [sp, #48]
145    .seh_save_fplr 48
146    stp x29, x30, [sp, #-32]!
147    .seh_save_fplr_x 32
148    stp d8, d9, [sp, #-48]!
149    .seh_save_fregp_x d8, 48
150    stp d10, d11, [sp, #32]
151    .seh_save_fregp d10, 32
152    str d12, [sp, #-32]!
153    .seh_save_freg_x d12, 32
154    str d13, [sp, #8]
155    .seh_save_freg d13, 8
156    add x29, sp, #16
157    .seh_add_fp 16
158    nop
159    .seh_nop
160    nop
161    .seh_trap_frame
162    nop
163    .seh_pushframe
164    nop
165    .seh_context
166    nop
167    .seh_ec_context
168    nop
169    .seh_clear_unwound_to_call
170    pacibsp
171    .seh_pac_sign_lr
172    nop
173    .seh_save_any_reg x0, 64
174    nop
175    .seh_save_any_reg_p x1, 64
176    nop
177    .seh_save_any_reg d29, 64
178    nop
179    .seh_save_any_reg_p d4, 64
180    nop
181    .seh_save_any_reg q30, 64
182    nop
183    .seh_save_any_reg_p q3, 64
184    nop
185    .seh_save_any_reg_x lr, 64
186    nop
187    .seh_save_any_reg_px fp, 64
188    nop
189    .seh_save_any_reg_x d31, 64
190    nop
191    .seh_save_any_reg_px d2, 64
192    nop
193    .seh_save_any_reg_x q29, 64
194    nop
195    .seh_save_any_reg_px q9, 64
196    .seh_endprologue
197    nop
198    .seh_startepilogue
199    add sp, sp, #24
200    .seh_stackalloc 24
201    .seh_endepilogue
202    ret
203    .seh_handler __C_specific_handler, @except
204    .seh_handlerdata
205    .long 0
206    .text
207    .seh_endproc
208
209    // Function with no .seh directives; no pdata/xdata entries are
210    // generated.
211    .globl smallFunc
212    .def smallFunc
213    .scl 2
214    .type 32
215    .endef
216    .seh_proc smallFunc
217smallFunc:
218    ret
219    .seh_endproc
220
221    // Function with no .seh directives, but with .seh_handlerdata.
222    // No xdata/pdata entries are generated, but the custom handler data
223    // (the .long after .seh_handlerdata) is left orphaned in the xdata
224    // section.
225    .globl handlerFunc
226    .def handlerFunc
227    .scl 2
228    .type 32
229    .endef
230    .seh_proc handlerFunc
231handlerFunc:
232    ret
233    .seh_handler __C_specific_handler, @except
234    .seh_handlerdata
235    .long 0
236    .text
237    .seh_endproc
238