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