237 lines
7.3 KiB
ArmAsm
237 lines
7.3 KiB
ArmAsm
// 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: 92
|
|
// 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: 0x50 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
|
|
// CHECK-NEXT: }
|
|
// CHECK-NEXT: Section (5) .pdata {
|
|
// CHECK-NEXT: 0x0 IMAGE_REL_ARM64_ADDR32NB .text
|
|
// 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: 156
|
|
// CHECK: Prologue [
|
|
// CHECK-NEXT: 0xe76983 ; stp q9, q10, [sp, #-64]!
|
|
// CHECK-NEXT: 0xe73d83 ; str q29, [sp, #-64]!
|
|
// CHECK-NEXT: 0xe76243 ; stp d2, d3, [sp, #-64]!
|
|
// CHECK-NEXT: 0xe73f43 ; str d31, [sp, #-64]!
|
|
// CHECK-NEXT: 0xe77d03 ; stp x29, x30, [sp, #-64]!
|
|
// CHECK-NEXT: 0xe73e03 ; str x30, [sp, #-64]!
|
|
// CHECK-NEXT: 0xe74384 ; stp q3, q4, [sp, #64]
|
|
// CHECK-NEXT: 0xe71e84 ; str q30, [sp, #64]
|
|
// CHECK-NEXT: 0xe74444 ; stp d4, d5, [sp, #64]
|
|
// CHECK-NEXT: 0xe71d48 ; str d29, [sp, #64]
|
|
// CHECK-NEXT: 0xe74104 ; stp x1, x2, [sp, #64]
|
|
// CHECK-NEXT: 0xe70008 ; str x0, [sp, #64]
|
|
// CHECK-NEXT: 0xfc ; pacibsp
|
|
// CHECK-NEXT: 0xec ; clear unwound to call
|
|
// CHECK-NEXT: 0xeb ; EC context
|
|
// 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: EpilogueScopes [
|
|
// CHECK-NEXT: EpilogueScope {
|
|
// CHECK-NEXT: StartOffset: 37
|
|
// CHECK-NEXT: EpilogueStartIndex: 69
|
|
// CHECK-NEXT: Opcodes [
|
|
// CHECK-NEXT: 0x01 ; add sp, #16
|
|
// CHECK-NEXT: 0xe4 ; end
|
|
// CHECK-NEXT: ]
|
|
// CHECK-NEXT: }
|
|
// 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_ec_context
|
|
nop
|
|
.seh_clear_unwound_to_call
|
|
pacibsp
|
|
.seh_pac_sign_lr
|
|
nop
|
|
.seh_save_any_reg x0, 64
|
|
nop
|
|
.seh_save_any_reg_p x1, 64
|
|
nop
|
|
.seh_save_any_reg d29, 64
|
|
nop
|
|
.seh_save_any_reg_p d4, 64
|
|
nop
|
|
.seh_save_any_reg q30, 64
|
|
nop
|
|
.seh_save_any_reg_p q3, 64
|
|
nop
|
|
.seh_save_any_reg_x lr, 64
|
|
nop
|
|
.seh_save_any_reg_px fp, 64
|
|
nop
|
|
.seh_save_any_reg_x d31, 64
|
|
nop
|
|
.seh_save_any_reg_px d2, 64
|
|
nop
|
|
.seh_save_any_reg_x q29, 64
|
|
nop
|
|
.seh_save_any_reg_px q9, 64
|
|
.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
|