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: 52
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:     0x28 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
45// CHECK-NEXT:   }
46// CHECK-NEXT:   Section (5) .pdata {
47// CHECK-NEXT:     0x0 IMAGE_REL_ARM64_ADDR32NB func
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: 100
58// CHECK:            Prologue [
59// CHECK-NEXT:         0xec                ; clear unwound to call
60// CHECK-NEXT:         0xea                ; context
61// CHECK-NEXT:         0xe9                ; machine frame
62// CHECK-NEXT:         0xe8                ; trap frame
63// CHECK-NEXT:         0xe3                ; nop
64// CHECK-NEXT:         0xe202              ; add fp, sp, #16
65// CHECK-NEXT:         0xdd41              ; str d13, [sp, #8]
66// CHECK-NEXT:         0xde83              ; str d12, [sp, #-32]!
67// CHECK-NEXT:         0xd884              ; stp d10, d11, [sp, #32]
68// CHECK-NEXT:         0xda05              ; stp d8, d9, [sp, #-48]!
69// CHECK-NEXT:         0x83                ; stp x29, x30, [sp, #-32]!
70// CHECK-NEXT:         0x46                ; stp x29, x30, [sp, #48]
71// CHECK-NEXT:         0xd141              ; str x24, [sp, #8]
72// CHECK-NEXT:         0xd483              ; str x23, [sp, #-32]!
73// CHECK-NEXT:         0xe6                ; save next
74// CHECK-NEXT:         0xc882              ; stp x21, x22, [sp, #16]
75// CHECK-NEXT:         0xd6c2              ; stp x25, lr, [sp, #16]
76// CHECK-NEXT:         0x24                ; stp x19, x20, [sp, #-32]!
77// CHECK-NEXT:         0xcc83              ; stp x21, x22, [sp, #-32]!
78// CHECK-NEXT:         0x83                ; stp x29, x30, [sp, #-32]!
79// CHECK-NEXT:         0xe1                ; mov fp, sp
80// CHECK-NEXT:         0x01                ; sub sp, #16
81// CHECK-NEXT:         0xe4                ; end
82// CHECK-NEXT:       ]
83// CHECK-NEXT:       Epilogue [
84// CHECK-NEXT:         0x01                ; add sp, #16
85// CHECK-NEXT:         0xe4                ; end
86// CHECK-NEXT:       ]
87// CHECK-NEXT:       ExceptionHandler [
88// CHECK-NEXT:         Routine: __C_specific_handler (0x0)
89// CHECK-NEXT:         Parameter: 0x0
90// CHECK-NEXT:       ]
91// CHECK-NEXT:     }
92// CHECK-NEXT:   }
93// CHECK-NEXT: ]
94
95
96    .text
97    .globl func
98    .def func
99    .scl 2
100    .type 32
101    .endef
102    .seh_proc func
103func:
104    sub sp, sp, #24
105    .seh_stackalloc 24
106    mov x29, sp
107    .seh_set_fp
108    stp x29, x30, [sp, #-32]!
109    .seh_save_fplr_x 32
110    stp x21, x22, [sp, #-32]!
111    .seh_save_regp_x x21, 32
112    stp x19, x20, [sp, #-32]!
113    .seh_save_r19r20_x 32
114    stp x25, x30, [sp, #16]
115    .seh_save_lrpair x25, 16
116    stp x21, x22, [sp, #16]
117    .seh_save_regp x21, 16
118    stp x23, x24, [sp, #32]
119    .seh_save_next
120    str x23, [sp, #-32]!
121    .seh_save_reg_x x23, 32
122    str x24, [sp, #8]
123    .seh_save_reg x24, 8
124    stp x29, x30, [sp, #48]
125    .seh_save_fplr 48
126    stp x29, x30, [sp, #-32]!
127    .seh_save_fplr_x 32
128    stp d8, d9, [sp, #-48]!
129    .seh_save_fregp_x d8, 48
130    stp d10, d11, [sp, #32]
131    .seh_save_fregp d10, 32
132    str d12, [sp, #-32]!
133    .seh_save_freg_x d12, 32
134    str d13, [sp, #8]
135    .seh_save_freg d13, 8
136    add x29, sp, #16
137    .seh_add_fp 16
138    nop
139    .seh_nop
140    nop
141    .seh_trap_frame
142    nop
143    .seh_pushframe
144    nop
145    .seh_context
146    nop
147    .seh_clear_unwound_to_call
148    .seh_endprologue
149    nop
150    .seh_startepilogue
151    add sp, sp, #24
152    .seh_stackalloc 24
153    .seh_endepilogue
154    ret
155    .seh_handler __C_specific_handler, @except
156    .seh_handlerdata
157    .long 0
158    .text
159    .seh_endproc
160
161    // Function with no .seh directives; no pdata/xdata entries are
162    // generated.
163    .globl smallFunc
164    .def smallFunc
165    .scl 2
166    .type 32
167    .endef
168    .seh_proc smallFunc
169smallFunc:
170    ret
171    .seh_endproc
172
173    // Function with no .seh directives, but with .seh_handlerdata.
174    // No xdata/pdata entries are generated, but the custom handler data
175    // (the .long after .seh_handlerdata) is left orphaned in the xdata
176    // section.
177    .globl handlerFunc
178    .def handlerFunc
179    .scl 2
180    .type 32
181    .endef
182    .seh_proc handlerFunc
183handlerFunc:
184    ret
185    .seh_handler __C_specific_handler, @except
186    .seh_handlerdata
187    .long 0
188    .text
189    .seh_endproc
190