seh.s
5.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// This test checks that the SEH directives emit the correct unwind data.
// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s | llvm-readobj -S -r -u - | FileCheck %s
// Check that the output assembler directives also can be parsed, and
// that they produce equivalent output:
// 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
// CHECK: Sections [
// CHECK: Section {
// CHECK: Name: .text
// CHECK: RelocationCount: 0
// CHECK: Characteristics [
// CHECK-NEXT: ALIGN_4BYTES
// CHECK-NEXT: CNT_CODE
// CHECK-NEXT: MEM_EXECUTE
// CHECK-NEXT: MEM_READ
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK: Section {
// CHECK: Name: .xdata
// CHECK: RawDataSize: 52
// CHECK: RelocationCount: 1
// CHECK: Characteristics [
// CHECK-NEXT: ALIGN_4BYTES
// CHECK-NEXT: CNT_INITIALIZED_DATA
// CHECK-NEXT: MEM_READ
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK: Section {
// CHECK: Name: .pdata
// CHECK: RelocationCount: 2
// CHECK: Characteristics [
// CHECK-NEXT: ALIGN_4BYTES
// CHECK-NEXT: CNT_INITIALIZED_DATA
// CHECK-NEXT: MEM_READ
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: Relocations [
// CHECK-NEXT: Section (4) .xdata {
// CHECK-NEXT: 0x28 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
// CHECK-NEXT: }
// CHECK-NEXT: Section (5) .pdata {
// CHECK-NEXT: 0x0 IMAGE_REL_ARM64_ADDR32NB func
// CHECK-NEXT: 0x4 IMAGE_REL_ARM64_ADDR32NB .xdata
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: UnwindInformation [
// CHECK-NEXT: RuntimeFunction {
// CHECK-NEXT: Function: func
// CHECK-NEXT: ExceptionRecord: .xdata
// CHECK-NEXT: ExceptionData {
// CHECK-NEXT: FunctionLength: 100
// CHECK: Prologue [
// CHECK-NEXT: 0xec ; clear unwound to call
// CHECK-NEXT: 0xea ; context
// CHECK-NEXT: 0xe9 ; machine frame
// CHECK-NEXT: 0xe8 ; trap frame
// CHECK-NEXT: 0xe3 ; nop
// CHECK-NEXT: 0xe202 ; add fp, sp, #16
// CHECK-NEXT: 0xdd41 ; str d13, [sp, #8]
// CHECK-NEXT: 0xde83 ; str d12, [sp, #-32]!
// CHECK-NEXT: 0xd884 ; stp d10, d11, [sp, #32]
// CHECK-NEXT: 0xda05 ; stp d8, d9, [sp, #-48]!
// CHECK-NEXT: 0x83 ; stp x29, x30, [sp, #-32]!
// CHECK-NEXT: 0x46 ; stp x29, x30, [sp, #48]
// CHECK-NEXT: 0xd141 ; str x24, [sp, #8]
// CHECK-NEXT: 0xd483 ; str x23, [sp, #-32]!
// CHECK-NEXT: 0xe6 ; save next
// CHECK-NEXT: 0xc882 ; stp x21, x22, [sp, #16]
// CHECK-NEXT: 0xd6c2 ; stp x25, lr, [sp, #16]
// CHECK-NEXT: 0x24 ; stp x19, x20, [sp, #-32]!
// CHECK-NEXT: 0xcc83 ; stp x21, x22, [sp, #-32]!
// CHECK-NEXT: 0x83 ; stp x29, x30, [sp, #-32]!
// CHECK-NEXT: 0xe1 ; mov fp, sp
// CHECK-NEXT: 0x01 ; sub sp, #16
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: Epilogue [
// CHECK-NEXT: 0x01 ; add sp, #16
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: ExceptionHandler [
// CHECK-NEXT: Routine: __C_specific_handler (0x0)
// CHECK-NEXT: Parameter: 0x0
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
.text
.globl func
.def func
.scl 2
.type 32
.endef
.seh_proc func
func:
sub sp, sp, #24
.seh_stackalloc 24
mov x29, sp
.seh_set_fp
stp x29, x30, [sp, #-32]!
.seh_save_fplr_x 32
stp x21, x22, [sp, #-32]!
.seh_save_regp_x x21, 32
stp x19, x20, [sp, #-32]!
.seh_save_r19r20_x 32
stp x25, x30, [sp, #16]
.seh_save_lrpair x25, 16
stp x21, x22, [sp, #16]
.seh_save_regp x21, 16
stp x23, x24, [sp, #32]
.seh_save_next
str x23, [sp, #-32]!
.seh_save_reg_x x23, 32
str x24, [sp, #8]
.seh_save_reg x24, 8
stp x29, x30, [sp, #48]
.seh_save_fplr 48
stp x29, x30, [sp, #-32]!
.seh_save_fplr_x 32
stp d8, d9, [sp, #-48]!
.seh_save_fregp_x d8, 48
stp d10, d11, [sp, #32]
.seh_save_fregp d10, 32
str d12, [sp, #-32]!
.seh_save_freg_x d12, 32
str d13, [sp, #8]
.seh_save_freg d13, 8
add x29, sp, #16
.seh_add_fp 16
nop
.seh_nop
nop
.seh_trap_frame
nop
.seh_pushframe
nop
.seh_context
nop
.seh_clear_unwound_to_call
.seh_endprologue
nop
.seh_startepilogue
add sp, sp, #24
.seh_stackalloc 24
.seh_endepilogue
ret
.seh_handler __C_specific_handler, @except
.seh_handlerdata
.long 0
.text
.seh_endproc
// Function with no .seh directives; no pdata/xdata entries are
// generated.
.globl smallFunc
.def smallFunc
.scl 2
.type 32
.endef
.seh_proc smallFunc
smallFunc:
ret
.seh_endproc
// Function with no .seh directives, but with .seh_handlerdata.
// No xdata/pdata entries are generated, but the custom handler data
// (the .long after .seh_handlerdata) is left orphaned in the xdata
// section.
.globl handlerFunc
.def handlerFunc
.scl 2
.type 32
.endef
.seh_proc handlerFunc
handlerFunc:
ret
.seh_handler __C_specific_handler, @except
.seh_handlerdata
.long 0
.text
.seh_endproc