309 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
| // This test checks that we emit unwind info correctly for epilogs that:
 | |
| // 1. mirror the prolog; or
 | |
| // 2. are subsequence at the end of the prolog; or
 | |
| // 3. neither of above two.
 | |
| // in the same segment. 
 | |
| // 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: 80
 | |
| // CHECK-NEXT:    PointerToRawData: 0x1251AC
 | |
| // 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: 16
 | |
| // CHECK-NEXT:    PointerToRawData: 0x1251FC
 | |
| // CHECK-NEXT:    PointerToRelocations: 0x12520C
 | |
| // CHECK-NEXT:    PointerToLineNumbers: 0x0
 | |
| // CHECK-NEXT:    RelocationCount: 4
 | |
| // 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:    0x94 IMAGE_REL_ARM64_BRANCH26 foo (12)
 | |
| // CHECK-NEXT:    0x125068 IMAGE_REL_ARM64_BRANCH26 foo (12)
 | |
| // CHECK-NEXT:  }
 | |
| // CHECK-NEXT:  Section (5) .pdata {
 | |
| // CHECK-NEXT:    0x0 IMAGE_REL_ARM64_ADDR32NB .text (0)
 | |
| // CHECK-NEXT:    0x4 IMAGE_REL_ARM64_ADDR32NB .xdata (7)
 | |
| // CHECK-NEXT:    0x8 IMAGE_REL_ARM64_ADDR32NB .text (0)
 | |
| // CHECK-NEXT:    0xC IMAGE_REL_ARM64_ADDR32NB .xdata (7)
 | |
| // CHECK-NEXT:  }
 | |
| // CHECK-NEXT:]
 | |
| // CHECK-LABEL:UnwindInformation [
 | |
| // CHECK-NEXT:  RuntimeFunction {
 | |
| // CHECK-NEXT:    Function: multi_epilog (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: 3
 | |
| // CHECK-NEXT:      ByteCodeLength: 24
 | |
| // CHECK-NEXT:      Prologue [
 | |
| // CHECK-NEXT:        0xe1                ; mov fp, sp
 | |
| // CHECK-NEXT:        0xca16              ; stp x27, x28, [sp, #176]
 | |
| // CHECK-NEXT:        0xc998              ; stp x25, x26, [sp, #192]
 | |
| // CHECK-NEXT:        0xc91a              ; stp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:        0xc89c              ; stp x21, x22, [sp, #224]
 | |
| // 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:        EpilogueScope {
 | |
| // CHECK-NEXT:          StartOffset: 38
 | |
| // CHECK-NEXT:          EpilogueStartIndex: 0
 | |
| // CHECK-NEXT:          Opcodes [
 | |
| // CHECK-NEXT:            0xe1                ; mov sp, fp
 | |
| // CHECK-NEXT:            0xca16              ; ldp x27, x28, [sp, #176]
 | |
| // CHECK-NEXT:            0xc998              ; ldp x25, x26, [sp, #192]
 | |
| // CHECK-NEXT:            0xc91a              ; ldp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:            0xc89c              ; ldp x21, x22, [sp, #224]
 | |
| // 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:        EpilogueScope {
 | |
| // CHECK-NEXT:          StartOffset: 46
 | |
| // CHECK-NEXT:          EpilogueStartIndex: 3
 | |
| // CHECK-NEXT:          Opcodes [
 | |
| // CHECK-NEXT:            0xc998              ; ldp x25, x26, [sp, #192]
 | |
| // CHECK-NEXT:            0xc91a              ; ldp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:            0xc89c              ; ldp x21, x22, [sp, #224]
 | |
| // 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:        EpilogueScope {
 | |
| // CHECK-NEXT:          StartOffset: 52
 | |
| // CHECK-NEXT:          EpilogueStartIndex: 13
 | |
| // CHECK-NEXT:          Opcodes [
 | |
| // CHECK-NEXT:            0xe1                ; mov sp, fp
 | |
| // CHECK-NEXT:            0xc91a              ; ldp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:            0xc89c              ; ldp x21, x22, [sp, #224]
 | |
| // 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:    }
 | |
| // CHECK-NEXT:  }
 | |
| // CHECK-NEXT:  RuntimeFunction {
 | |
| // CHECK-NEXT:    Function: multi_epilog +0xFFFFC (0xFFFFC)
 | |
| // CHECK-NEXT:    ExceptionRecord: .xdata +0x28 (0x28)
 | |
| // CHECK-NEXT:    ExceptionData {
 | |
| // CHECK-NEXT:      FunctionLength: 151744
 | |
| // CHECK-NEXT:      Version: 0
 | |
| // CHECK-NEXT:      ExceptionData: No
 | |
| // CHECK-NEXT:      EpiloguePacked: No
 | |
| // CHECK-NEXT:      EpilogueScopes: 3
 | |
| // CHECK-NEXT:      ByteCodeLength: 24
 | |
| // CHECK-NEXT:      Prologue [
 | |
| // CHECK-NEXT:        0xe5                ; end_c
 | |
| // CHECK-NEXT:        0xe1                ; mov fp, sp
 | |
| // CHECK-NEXT:        0xca16              ; stp x27, x28, [sp, #176]
 | |
| // CHECK-NEXT:        0xc998              ; stp x25, x26, [sp, #192]
 | |
| // CHECK-NEXT:        0xc91a              ; stp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:        0xc89c              ; stp x21, x22, [sp, #224]
 | |
| // 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:        EpilogueScope {
 | |
| // CHECK-NEXT:          StartOffset: 37916
 | |
| // CHECK-NEXT:          EpilogueStartIndex: 1
 | |
| // CHECK-NEXT:          Opcodes [
 | |
| // CHECK-NEXT:            0xe1                ; mov sp, fp
 | |
| // CHECK-NEXT:            0xca16              ; ldp x27, x28, [sp, #176]
 | |
| // CHECK-NEXT:            0xc998              ; ldp x25, x26, [sp, #192]
 | |
| // CHECK-NEXT:            0xc91a              ; ldp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:            0xc89c              ; ldp x21, x22, [sp, #224]
 | |
| // 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:        EpilogueScope {
 | |
| // CHECK-NEXT:          StartOffset: 37924
 | |
| // CHECK-NEXT:          EpilogueStartIndex: 4
 | |
| // CHECK-NEXT:          Opcodes [
 | |
| // CHECK-NEXT:            0xc998              ; ldp x25, x26, [sp, #192]
 | |
| // CHECK-NEXT:            0xc91a              ; ldp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:            0xc89c              ; ldp x21, x22, [sp, #224]
 | |
| // 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:        EpilogueScope {
 | |
| // CHECK-NEXT:          StartOffset: 37930
 | |
| // CHECK-NEXT:          EpilogueStartIndex: 14
 | |
| // CHECK-NEXT:          Opcodes [
 | |
| // CHECK-NEXT:            0xe1                ; mov sp, fp
 | |
| // CHECK-NEXT:            0xc91a              ; ldp x23, x24, [sp, #208]
 | |
| // CHECK-NEXT:            0xc89c              ; ldp x21, x22, [sp, #224]
 | |
| // 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:    }
 | |
| // CHECK-NEXT:  }
 | |
| // CHECK-NEXT:]
 | |
| 
 | |
| 	.text
 | |
| 	.global	multi_epilog
 | |
| 	.p2align	2
 | |
| 	.seh_proc multi_epilog
 | |
| multi_epilog:
 | |
| 	stp	x29, lr, [sp, #-256]!
 | |
| 	.seh_save_fplr_x 256
 | |
| 	stp	x19, x20, [sp, #240]
 | |
| 	.seh_save_regp x19, 240
 | |
| 	stp	x21, x22, [sp, #224]
 | |
| 	.seh_save_regp x21, 224
 | |
| 	stp	x23, x24, [sp, #208]
 | |
| 	.seh_save_regp x23, 208
 | |
| 	stp	x25, x26, [sp, #192]
 | |
| 	.seh_save_regp x25, 192
 | |
| 	stp	x27, x28, [sp, #176]
 | |
| 	.seh_save_regp x27, 176
 | |
| 	mov	x29, fp
 | |
| 	.seh_set_fp
 | |
| 	.seh_endprologue
 | |
|         .rept 30
 | |
|         nop
 | |
|         .endr
 | |
| 	bl	foo
 | |
| // Epilogs 1, 2 and 3 are in the same segment as prolog.
 | |
| // epilog1 - mirroring prolog
 | |
| 	.seh_startepilogue
 | |
| 	mov	sp, x29
 | |
| 	.seh_set_fp
 | |
| 	stp	x27, x28, [sp, #176]
 | |
| 	.seh_save_regp x27, 176
 | |
| 	stp	x25, x26, [sp, #192]
 | |
| 	.seh_save_regp x25, 192
 | |
| 	stp	x23, x24, [sp, #208]
 | |
| 	.seh_save_regp x23, 208
 | |
| 	stp	x21, x22, [sp, #224]
 | |
| 	.seh_save_regp x21, 224
 | |
| 	ldp	x19, x20, [sp, #240]
 | |
| 	.seh_save_regp x19, 240
 | |
| 	ldp	x29, lr, [sp], #256
 | |
| 	.seh_save_fplr_x 256
 | |
| 	.seh_endepilogue
 | |
| 	ret
 | |
| // epilog2 - a subsequence at the end of prolog, can use prolog's opcodes.
 | |
| 	.seh_startepilogue
 | |
| 	stp	x25, x26, [sp, #192]
 | |
| 	.seh_save_regp x25, 192
 | |
| 	stp	x23, x24, [sp, #208]
 | |
| 	.seh_save_regp x23, 208
 | |
| 	stp	x21, x22, [sp, #224]
 | |
| 	.seh_save_regp x21, 224
 | |
| 	ldp	x19, x20, [sp, #240]
 | |
| 	.seh_save_regp x19, 240
 | |
| 	ldp	x29, lr, [sp], #256
 | |
| 	.seh_save_fplr_x 256
 | |
| 	.seh_endepilogue
 | |
| 	ret
 | |
| // epilog3 - cannot use prolog's opcode.
 | |
| 	.seh_startepilogue
 | |
| 	mov	sp, x29
 | |
| 	.seh_set_fp
 | |
| 	stp	x23, x24, [sp, #208]
 | |
| 	.seh_save_regp x23, 208
 | |
| 	stp	x21, x22, [sp, #224]
 | |
| 	.seh_save_regp x21, 224
 | |
| 	ldp	x19, x20, [sp, #240]
 | |
| 	.seh_save_regp x19, 240
 | |
| 	ldp	x29, lr, [sp], #256
 | |
| 	.seh_save_fplr_x 256
 | |
| 	.seh_endepilogue
 | |
| 	ret
 | |
|         .rept 300000
 | |
|         nop
 | |
|         .endr
 | |
| 	bl	foo
 | |
| // Epilogs below are in a segment without prolog
 | |
| // epilog4 - mirroring prolog, its start index should be 1, counting the end_c. 
 | |
| 	.seh_startepilogue
 | |
| 	mov	sp, x29
 | |
| 	.seh_set_fp
 | |
| 	stp	x27, x28, [sp, #176]
 | |
| 	.seh_save_regp x27, 176
 | |
| 	stp	x25, x26, [sp, #192]
 | |
| 	.seh_save_regp x25, 192
 | |
| 	stp	x23, x24, [sp, #208]
 | |
| 	.seh_save_regp x23, 208
 | |
| 	stp	x21, x22, [sp, #224]
 | |
| 	.seh_save_regp x21, 224
 | |
| 	ldp	x19, x20, [sp, #240]
 | |
| 	.seh_save_regp x19, 240
 | |
| 	ldp	x29, lr, [sp], #256
 | |
| 	.seh_save_fplr_x 256
 | |
| 	.seh_endepilogue
 | |
| 	ret
 | |
| // epilog5 - same as epilog2, its start index should be: 1 + epilog2's index.
 | |
| 	.seh_startepilogue
 | |
| 	stp	x25, x26, [sp, #192]
 | |
| 	.seh_save_regp x25, 192
 | |
| 	stp	x23, x24, [sp, #208]
 | |
| 	.seh_save_regp x23, 208
 | |
| 	stp	x21, x22, [sp, #224]
 | |
| 	.seh_save_regp x21, 224
 | |
| 	ldp	x19, x20, [sp, #240]
 | |
| 	.seh_save_regp x19, 240
 | |
| 	ldp	x29, lr, [sp], #256
 | |
| 	.seh_save_fplr_x 256
 | |
| 	.seh_endepilogue
 | |
| 	ret
 | |
| // epilog6 - same as epilog3, cannot use prolog's opcode. Again its start index
 | |
| //           should be: 1 + epilog3's index.
 | |
| 	.seh_startepilogue
 | |
| 	mov	sp, x29
 | |
| 	.seh_set_fp
 | |
| 	stp	x23, x24, [sp, #208]
 | |
| 	.seh_save_regp x23, 208
 | |
| 	stp	x21, x22, [sp, #224]
 | |
| 	.seh_save_regp x21, 224
 | |
| 	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
 |