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 | |
14 | typedef 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 | |
45 | static const UCHAR [] = { |
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 | |
67 | typedef 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 | |
94 | typedef struct _UNWIND_INFO { |
95 | ULONG FunctionLength; |
96 | } UNWIND_INFO, *PUNWIND_INFO; |
97 | |
98 | #else // _TARGET_X86_ |
99 | |
100 | typedef 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 | |