1 // This test checks that the SEH directives emit the correct unwind data. 2 3 // RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-readobj -s -u -r | FileCheck %s 4 5 // CHECK: Sections [ 6 // CHECK: Section { 7 // CHECK: Name: .text 8 // CHECK: RelocationCount: 0 9 // CHECK: Characteristics [ 10 // CHECK-NEXT: ALIGN_4BYTES 11 // CHECK-NEXT: CNT_CODE 12 // CHECK-NEXT: MEM_EXECUTE 13 // CHECK-NEXT: MEM_READ 14 // CHECK-NEXT: ] 15 // CHECK-NEXT: } 16 // CHECK: Section { 17 // CHECK: Name: .xdata 18 // CHECK: RawDataSize: 52 19 // CHECK: RelocationCount: 4 20 // CHECK: Characteristics [ 21 // CHECK-NEXT: ALIGN_4BYTES 22 // CHECK-NEXT: CNT_INITIALIZED_DATA 23 // CHECK-NEXT: MEM_READ 24 // CHECK-NEXT: ] 25 // CHECK-NEXT: } 26 // CHECK: Section { 27 // CHECK: Name: .pdata 28 // CHECK: RelocationCount: 9 29 // CHECK: Characteristics [ 30 // CHECK-NEXT: ALIGN_4BYTES 31 // CHECK-NEXT: CNT_INITIALIZED_DATA 32 // CHECK-NEXT: MEM_READ 33 // CHECK-NEXT: ] 34 // CHECK-NEXT: } 35 // CHECK-NEXT: ] 36 37 // CHECK-NEXT: Relocations [ 38 // CHECK-NEXT: Section (4) .xdata { 39 // CHECK-NEXT: 0x14 IMAGE_REL_AMD64_ADDR32NB __C_specific_handler 40 // CHECK-NEXT: 0x20 IMAGE_REL_AMD64_ADDR32NB func 41 // CHECK-NEXT: 0x24 IMAGE_REL_AMD64_ADDR32NB func 42 // CHECK-NEXT: 0x28 IMAGE_REL_AMD64_ADDR32NB .xdata 43 // CHECK-NEXT: } 44 // CHECK-NEXT: Section (5) .pdata { 45 // CHECK-NEXT: 0x0 IMAGE_REL_AMD64_ADDR32NB func 46 // CHECK-NEXT: 0x4 IMAGE_REL_AMD64_ADDR32NB func 47 // CHECK-NEXT: 0x8 IMAGE_REL_AMD64_ADDR32NB .xdata 48 // CHECK-NEXT: 0xC IMAGE_REL_AMD64_ADDR32NB func 49 // CHECK-NEXT: 0x10 IMAGE_REL_AMD64_ADDR32NB func 50 // CHECK-NEXT: 0x14 IMAGE_REL_AMD64_ADDR32NB .xdata 51 // CHECK-NEXT: 0x18 IMAGE_REL_AMD64_ADDR32NB smallFunc 52 // CHECK-NEXT: 0x1C IMAGE_REL_AMD64_ADDR32NB smallFunc 53 // CHECK-NEXT: 0x20 IMAGE_REL_AMD64_ADDR32NB .xdata 54 // CHECK-NEXT: } 55 // CHECK-NEXT: ] 56 57 58 // CHECK: UnwindInformation [ 59 // CHECK-NEXT: RuntimeFunction { 60 // CHECK-NEXT: StartAddress: [[CodeSect1:[^ ]+]] [[BeginDisp1:(\+0x[A-F0-9]+)?]] 61 // CHECK-NEXT: EndAddress: [[CodeSect1]] [[EndDisp1:(\+0x[A-F0-9]+)?]] 62 // CHECK-NEXT: UnwindInfoAddress: 63 // CHECK-NEXT: UnwindInfo { 64 // CHECK-NEXT: Version: 1 65 // CHECK-NEXT: Flags [ 66 // CHECK-NEXT: ExceptionHandler 67 // CHECK-NEXT: ] 68 // CHECK-NEXT: PrologSize: 18 69 // CHECK-NEXT: FrameRegister: RBX 70 // CHECK-NEXT: FrameOffset: 0x0 71 // CHECK-NEXT: UnwindCodeCount: 8 72 // CHECK-NEXT: UnwindCodes [ 73 // CHECK-NEXT: 0x12: SET_FPREG reg=RBX, offset=0x0 74 // CHECK-NEXT: 0x0F: PUSH_NONVOL reg=RBX 75 // CHECK-NEXT: 0x0E: SAVE_XMM128 reg=XMM8, offset=0x0 76 // CHECK-NEXT: 0x09: SAVE_NONVOL reg=RSI, offset=0x10 77 // CHECK-NEXT: 0x04: ALLOC_SMALL size=24 78 // CHECK-NEXT: 0x00: PUSH_MACHFRAME errcode=yes 79 // CHECK-NEXT: ] 80 // CHECK-NEXT: Handler: __C_specific_handler 81 // CHECK-NEXT: } 82 // CHECK-NEXT: } 83 // CHECK-NEXT: RuntimeFunction { 84 // CHECK-NEXT: StartAddress: [[CodeSect2:[^ ]+]] [[BeginDisp2:(\+0x[A-F0-9]+)?]] 85 // CHECK-NEXT: EndAddress: [[CodeSect2]] [[BeginDisp2:(\+0x[A-F0-9]+)?]] 86 // CHECK-NEXT: UnwindInfoAddress: 87 // CHECK-NEXT: UnwindInfo { 88 // CHECK-NEXT: Version: 1 89 // CHECK-NEXT: Flags [ 90 // CHECK-NEXT: ChainInfo 91 // CHECK-NEXT: ] 92 // CHECK-NEXT: PrologSize: 0 93 // CHECK-NEXT: FrameRegister: - 94 // CHECK-NEXT: FrameOffset: - 95 // CHECK-NEXT: UnwindCodeCount: 0 96 // CHECK-NEXT: UnwindCodes [ 97 // CHECK-NEXT: ] 98 // CHECK-NEXT: Chained { 99 // CHECK-NEXT: StartAddress: [[CodeSect1]] [[BeginDisp1]] 100 // CHECK-NEXT: EndAddress: [[CodeSect1]] [[EndDisp1]] 101 // CHECK-NEXT: UnwindInfoAddress: 102 // CHECK-NEXT: } 103 // CHECK-NEXT: } 104 // CHECK-NEXT: } 105 // CHECK-NEXT: RuntimeFunction { 106 // CHECK-NEXT: StartAddress: [[CodeSect3:[^ ]+]] [[BeginDisp3:(\+0x[A-F0-9]+)?]] 107 // CHECK-NEXT: EndAddress: [[CodeSect3]] [[BeginDisp3:(\+0x[A-F0-9]+)?]] 108 // CHECK-NEXT: UnwindInfoAddress: 109 // CHECK-NEXT: UnwindInfo { 110 // CHECK-NEXT: Version: 1 111 // CHECK-NEXT: Flags [ 112 // CHECK-NEXT: ] 113 // CHECK-NEXT: PrologSize: 0 114 // CHECK-NEXT: FrameRegister: - 115 // CHECK-NEXT: FrameOffset: - 116 // CHECK-NEXT: UnwindCodeCount: 0 117 // CHECK-NEXT: UnwindCodes [ 118 // CHECK-NEXT: ] 119 // CHECK-NEXT: } 120 // CHECK-NEXT: } 121 // CHECK-NEXT: ] 122 123 .text 124 .globl func 125 .def func; .scl 2; .type 32; .endef 126 .seh_proc func 127 func: 128 .seh_pushframe @code 129 subq $24, %rsp 130 .seh_stackalloc 24 131 movq %rsi, 16(%rsp) 132 .seh_savereg %rsi, 16 133 movups %xmm8, (%rsp) 134 .seh_savexmm %xmm8, 0 135 pushq %rbx 136 .seh_pushreg 3 137 mov %rsp, %rbx 138 .seh_setframe 3, 0 139 .seh_endprologue 140 .seh_handler __C_specific_handler, @except 141 .seh_handlerdata 142 .long 0 143 .text 144 .seh_startchained 145 .seh_endprologue 146 .seh_endchained 147 lea (%rbx), %rsp 148 pop %rbx 149 addq $24, %rsp 150 ret 151 .seh_endproc 152 153 // Test emission of small functions. 154 .globl smallFunc 155 .def smallFunc; .scl 2; .type 32; .endef 156 .seh_proc smallFunc 157 smallFunc: 158 ret 159 .seh_endproc 160