190 lines
5.7 KiB
ArmAsm
190 lines
5.7 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: 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
|