1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5#ifndef _WIN64UNWIND_H_
6#define _WIN64UNWIND_H_
7
8//
9// Define AMD64 exception handling structures and function prototypes.
10//
11// Define unwind operation codes.
12//
13
14typedef enum _UNWIND_OP_CODES {
15 UWOP_PUSH_NONVOL = 0,
16 UWOP_ALLOC_LARGE,
17 UWOP_ALLOC_SMALL,
18 UWOP_SET_FPREG,
19 UWOP_SAVE_NONVOL,
20 UWOP_SAVE_NONVOL_FAR,
21 UWOP_EPILOG,
22 UWOP_SPARE_CODE,
23 UWOP_SAVE_XMM128,
24 UWOP_SAVE_XMM128_FAR,
25 UWOP_PUSH_MACHFRAME,
26
27#ifdef PLATFORM_UNIX
28 // UWOP_SET_FPREG_LARGE is a CLR Unix-only extension to the Windows AMD64 unwind codes.
29 // It is not part of the standard Windows AMD64 unwind codes specification.
30 // UWOP_SET_FPREG allows for a maximum of a 240 byte offset between RSP and the
31 // frame pointer, when the frame pointer is established. UWOP_SET_FPREG_LARGE
32 // has a 32-bit range scaled by 16. When UWOP_SET_FPREG_LARGE is used,
33 // UNWIND_INFO.FrameRegister must be set to the frame pointer register, and
34 // UNWIND_INFO.FrameOffset must be set to 15 (its maximum value). UWOP_SET_FPREG_LARGE
35 // is followed by two UNWIND_CODEs that are combined to form a 32-bit offset (the same
36 // as UWOP_SAVE_NONVOL_FAR). This offset is then scaled by 16. The result must be less
37 // than 2^32 (that is, the top 4 bits of the unscaled 32-bit number must be zero). This
38 // result is used as the frame pointer register offset from RSP at the time the frame pointer
39 // is established. Either UWOP_SET_FPREG or UWOP_SET_FPREG_LARGE can be used, but not both.
40
41 UWOP_SET_FPREG_LARGE,
42#endif // PLATFORM_UNIX
43} UNWIND_OP_CODES, *PUNWIND_OP_CODES;
44
45static const UCHAR UnwindOpExtraSlotTable[] = {
46 0, // UWOP_PUSH_NONVOL
47 1, // UWOP_ALLOC_LARGE (or 3, special cased in lookup code)
48 0, // UWOP_ALLOC_SMALL
49 0, // UWOP_SET_FPREG
50 1, // UWOP_SAVE_NONVOL
51 2, // UWOP_SAVE_NONVOL_FAR
52 1, // UWOP_EPILOG
53 2, // UWOP_SPARE_CODE // previously 64-bit UWOP_SAVE_XMM_FAR
54 1, // UWOP_SAVE_XMM128
55 2, // UWOP_SAVE_XMM128_FAR
56 0, // UWOP_PUSH_MACHFRAME
57
58#ifdef PLATFORM_UNIX
59 2, // UWOP_SET_FPREG_LARGE
60#endif // PLATFORM_UNIX
61};
62
63//
64// Define unwind code structure.
65//
66
67typedef union _UNWIND_CODE {
68 struct {
69 UCHAR CodeOffset;
70 UCHAR UnwindOp : 4;
71 UCHAR OpInfo : 4;
72 };
73
74 struct {
75 UCHAR OffsetLow;
76 UCHAR UnwindOp : 4;
77 UCHAR OffsetHigh : 4;
78 } EpilogueCode;
79
80 USHORT FrameOffset;
81} UNWIND_CODE, *PUNWIND_CODE;
82
83//
84// Define unwind information flags.
85//
86
87#define UNW_FLAG_NHANDLER 0x0
88#define UNW_FLAG_EHANDLER 0x1
89#define UNW_FLAG_UHANDLER 0x2
90#define UNW_FLAG_CHAININFO 0x4
91
92#ifdef _TARGET_X86_
93
94typedef struct _UNWIND_INFO {
95 ULONG FunctionLength;
96} UNWIND_INFO, *PUNWIND_INFO;
97
98#else // _TARGET_X86_
99
100typedef struct _UNWIND_INFO {
101 UCHAR Version : 3;
102 UCHAR Flags : 5;
103 UCHAR SizeOfProlog;
104 UCHAR CountOfUnwindCodes;
105 UCHAR FrameRegister : 4;
106 UCHAR FrameOffset : 4;
107 UNWIND_CODE UnwindCode[1];
108
109//
110// The unwind codes are followed by an optional DWORD aligned field that
111// contains the exception handler address or the address of chained unwind
112// information. If an exception handler address is specified, then it is
113// followed by the language specified exception handler data.
114//
115// union {
116// ULONG ExceptionHandler;
117// ULONG FunctionEntry;
118// };
119//
120// ULONG ExceptionData[];
121//
122
123} UNWIND_INFO, *PUNWIND_INFO;
124
125#endif // _TARGET_X86_
126#endif // _WIN64UNWIND_H_
127