blob: d9defe6b18743a5248e4a7dd7157292d6bb5d7d9 [file] [log] [blame]
// This test checks that we emit unwind info correctly for functions
// larger than 1MB.
// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o
// RUN: llvm-readobj -S -r -u %t.o | FileCheck %s
// CHECK: Section {
// CHECK: Number: 4
// CHECK-NEXT: Name: .xdata (2E 78 64 61 74 61 00 00)
// CHECK-NEXT: VirtualSize: 0x0
// CHECK-NEXT: VirtualAddress: 0x0
// CHECK-NEXT: RawDataSize: 52
// CHECK-NEXT: PointerToRawData: 0x3D0A20
// CHECK-NEXT: PointerToRelocations: 0x0
// CHECK-NEXT: PointerToLineNumbers: 0x0
// CHECK-NEXT: RelocationCount: 0
// CHECK-NEXT: LineNumberCount: 0
// CHECK-NEXT: Characteristics [ (0x40300040)
// CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
// CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: Section {
// CHECK-NEXT: Number: 5
// CHECK-NEXT: Name: .pdata (2E 70 64 61 74 61 00 00)
// CHECK-NEXT: VirtualSize: 0x0
// CHECK-NEXT: VirtualAddress: 0x0
// CHECK-NEXT: RawDataSize: 40
// CHECK-NEXT: PointerToRawData: 0x3D0A54
// CHECK-NEXT: PointerToRelocations: 0x3D0A7C
// CHECK-NEXT: PointerToLineNumbers: 0x0
// CHECK-NEXT: RelocationCount: 10
// CHECK-NEXT: LineNumberCount: 0
// CHECK-NEXT: Characteristics [ (0x40300040)
// CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
// CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-LABEL: Relocations [
// CHECK-NEXT: Section (1) .text {
// CHECK-NEXT: 0x186A04 IMAGE_REL_ARM64_BRANCH26 foo (14)
// CHECK-NEXT: 0x3D091C IMAGE_REL_ARM64_BRANCH26 foo (14)
// CHECK-NEXT: }
// CHECK-NEXT: Section (5) .pdata {
// CHECK-NEXT: 0x0 IMAGE_REL_ARM64_ADDR32NB .text (0)
// CHECK-NEXT: 0x4 IMAGE_REL_ARM64_ADDR32NB .xdata (9)
// CHECK-NEXT: 0x8 IMAGE_REL_ARM64_ADDR32NB .text (0)
// CHECK-NEXT: 0xC IMAGE_REL_ARM64_ADDR32NB .xdata (9)
// CHECK-NEXT: 0x10 IMAGE_REL_ARM64_ADDR32NB $L.text_1 (2)
// CHECK-NEXT: 0x14 IMAGE_REL_ARM64_ADDR32NB .xdata (9)
// CHECK-NEXT: 0x18 IMAGE_REL_ARM64_ADDR32NB $L.text_2 (3)
// CHECK-NEXT: 0x1C IMAGE_REL_ARM64_ADDR32NB .xdata (9)
// CHECK-NEXT: 0x20 IMAGE_REL_ARM64_ADDR32NB $L.text_3 (4)
// CHECK-NEXT: 0x24 IMAGE_REL_ARM64_ADDR32NB .xdata (9)
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-LABEL: UnwindInformation [
// CHECK-NEXT: RuntimeFunction {
// CHECK-NEXT: Function: a (0x0)
// CHECK-NEXT: ExceptionRecord: .xdata (0x0)
// CHECK-NEXT: ExceptionData {
// CHECK-NEXT: FunctionLength: 1048572
// CHECK-NEXT: Version: 0
// CHECK-NEXT: ExceptionData: No
// CHECK-NEXT: EpiloguePacked: No
// CHECK-NEXT: EpilogueScopes: 0
// CHECK-NEXT: ByteCodeLength: 4
// CHECK-NEXT: Prologue [
// CHECK-NEXT: 0xd561 ; str x30, [sp, #-16]!
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: EpilogueScopes [
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: RuntimeFunction {
// CHECK-NEXT: Function: a +0xFFFFC (0xFFFFC)
// CHECK-NEXT: ExceptionRecord: .xdata +0x8 (0x8)
// CHECK-NEXT: ExceptionData {
// CHECK-NEXT: FunctionLength: 551444
// CHECK-NEXT: Version: 0
// CHECK-NEXT: ExceptionData: No
// CHECK-NEXT: EpiloguePacked: Yes
// CHECK-NEXT: EpilogueOffset: 1
// CHECK-NEXT: ByteCodeLength: 4
// CHECK-NEXT: Prologue [
// CHECK-NEXT: 0xe5 ; end_c
// CHECK-NEXT: 0xd561 ; str x30, [sp, #-16]!
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: Epilogue [
// CHECK-NEXT: 0xd561 ; ldr x30, [sp], #16
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: RuntimeFunction {
// CHECK-NEXT: Function: b (0x186A10)
// CHECK-NEXT: ExceptionRecord: .xdata +0x10 (0x10)
// CHECK-NEXT: ExceptionData {
// CHECK-NEXT: FunctionLength: 1048572
// CHECK-NEXT: Version: 0
// CHECK-NEXT: ExceptionData: No
// CHECK-NEXT: EpiloguePacked: No
// CHECK-NEXT: EpilogueScopes: 0
// CHECK-NEXT: ByteCodeLength: 8
// CHECK-NEXT: Prologue [
// CHECK-NEXT: 0xe1 ; mov fp, sp
// CHECK-NEXT: 0xc81e ; stp x19, x20, [sp, #240]
// CHECK-NEXT: 0x9f ; stp x29, x30, [sp, #-256]!
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: EpilogueScopes [
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: RuntimeFunction {
// CHECK-NEXT: Function: $L.text_2 +0x86A0C (0x286A0C)
// CHECK-NEXT: ExceptionRecord: .xdata +0x1C (0x1C)
// CHECK-NEXT: ExceptionData {
// CHECK-NEXT: FunctionLength: 1048572
// CHECK-NEXT: Version: 0
// CHECK-NEXT: ExceptionData: No
// CHECK-NEXT: EpiloguePacked: Yes
// CHECK-NEXT: EpilogueOffset: 0
// CHECK-NEXT: ByteCodeLength: 8
// CHECK-NEXT: Prologue [
// CHECK-NEXT: 0xe5 ; end_c
// CHECK-NEXT: 0xe1 ; mov fp, sp
// CHECK-NEXT: 0xc81e ; stp x19, x20, [sp, #240]
// CHECK-NEXT: 0x9f ; stp x29, x30, [sp, #-256]!
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: RuntimeFunction {
// CHECK-NEXT: Function: $L.text_3 +0x86A08 (0x386A08)
// CHECK-NEXT: ExceptionRecord: .xdata +0x28 (0x28)
// CHECK-NEXT: ExceptionData {
// CHECK-NEXT: FunctionLength: 302888
// CHECK-NEXT: Version: 0
// CHECK-NEXT: ExceptionData: No
// CHECK-NEXT: EpiloguePacked: Yes
// CHECK-NEXT: EpilogueOffset: 1
// CHECK-NEXT: ByteCodeLength: 8
// CHECK-NEXT: Prologue [
// CHECK-NEXT: 0xe5 ; end_c
// CHECK-NEXT: 0xe1 ; mov fp, sp
// CHECK-NEXT: 0xc81e ; stp x19, x20, [sp, #240]
// CHECK-NEXT: 0x9f ; stp x29, x30, [sp, #-256]!
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: Epilogue [
// CHECK-NEXT: 0xe1 ; mov sp, fp
// CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]
// CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256
// CHECK-NEXT: 0xe4 ; end
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
.text
// A simple function with an single epilog mirroring the prolog.
.global a
.p2align 2
.seh_proc a
a:
str x30, [sp, #-16]!
.seh_save_reg_x x30, 16
.seh_endprologue
.rept 400000
nop
.endr
bl foo
.seh_startepilogue
ldr x30, [sp], #16
.seh_save_reg_x x30, 16
.seh_endepilogue
ret
.seh_endfunclet
.seh_endproc
// Example 1 from https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling#function-fragments
.global b
.p2align 2
.seh_proc b
b:
stp x29, lr, [sp, #-256]!
.seh_save_fplr_x 256
stp x19, x20, [sp, #240]
.seh_save_regp x19, 240
mov x29, fp
.seh_set_fp
.seh_endprologue
.rept 600000
nop
.endr
bl foo
.seh_startepilogue
mov sp, x29
.seh_set_fp
ldp x19, x20, [sp, #240]
.seh_save_regp x19, 240
ldp x29, lr, [sp], #256
.seh_save_fplr_x 256
.seh_endepilogue
ret
.seh_endfunclet
.seh_endproc