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