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
127func:
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
157smallFunc:
158    ret
159    .seh_endproc
160