6#ifndef RUNTIME_PLATFORM_UNWINDING_RECORDS_H_
7#define RUNTIME_PLATFORM_UNWINDING_RECORDS_H_
19 void** pp_dynamic_table);
23#if (defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS)) && \
24 defined(TARGET_ARCH_X64)
30typedef unsigned char UBYTE;
31typedef uint16_t USHORT;
32typedef union _UNWIND_CODE {
39} UNWIND_CODE, *PUNWIND_CODE;
41typedef struct _UNWIND_INFO {
46 UBYTE FrameRegister : 4;
47 UBYTE FrameOffset : 4;
48 UNWIND_CODE UnwindCode[2];
49} UNWIND_INFO, *PUNWIND_INFO;
51#if !defined(DART_HOST_OS_WINDOWS)
52typedef uint32_t
ULONG;
53typedef struct _RUNTIME_FUNCTION {
57} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
60static constexpr int kPushRbpInstructionLength = 1;
61static const int kMovRbpRspInstructionLength = 3;
62static constexpr int kRbpPrefixLength =
63 kPushRbpInstructionLength + kMovRbpRspInstructionLength;
64static constexpr int kRBP = 5;
66#ifndef UNW_FLAG_NHANDLER
67#define UNW_FLAG_NHANDLER 0
70struct GeneratedCodeUnwindInfo {
71 UNWIND_INFO unwind_info;
73 GeneratedCodeUnwindInfo() {
74 unwind_info.Version = 1;
75 unwind_info.Flags = UNW_FLAG_NHANDLER;
76 unwind_info.SizeOfProlog = kRbpPrefixLength;
77 unwind_info.CountOfCodes = 2;
78 unwind_info.FrameRegister = kRBP;
79 unwind_info.FrameOffset = 0;
80 unwind_info.UnwindCode[0].CodeOffset = kRbpPrefixLength;
81 unwind_info.UnwindCode[0].UnwindOp = 3;
82 unwind_info.UnwindCode[0].OpInfo = 0;
83 unwind_info.UnwindCode[1].CodeOffset = kPushRbpInstructionLength;
84 unwind_info.UnwindCode[1].UnwindOp = 0;
85 unwind_info.UnwindCode[1].OpInfo = kRBP;
89static constexpr uint32_t kUnwindingRecordMagic = 0xAABBCCDD;
91struct CodeRangeUnwindingRecord {
94 uint32_t runtime_function_count;
95 GeneratedCodeUnwindInfo unwind_info;
96 intptr_t exception_handler;
97 RUNTIME_FUNCTION runtime_function[1];
102#elif defined(TARGET_ARCH_ARM64) && \
103 (defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS))
119typedef uint32_t UNWIND_CODE;
121constexpr UNWIND_CODE Combine8BitUnwindCodes(uint8_t code0 = OpNop,
122 uint8_t code1 = OpNop,
123 uint8_t code2 = OpNop,
124 uint8_t code3 = OpNop) {
125 return static_cast<uint32_t
>(code0) | (
static_cast<uint32_t
>(code1) << 8) |
126 (
static_cast<uint32_t
>(code2) << 16) |
127 (
static_cast<uint32_t
>(code3) << 24);
134 uint32_t FunctionLength : 18;
138 uint32_t EpilogCount : 5;
139 uint32_t CodeWords : 5;
142#if !defined(DART_HOST_OS_WINDOWS)
143typedef uint32_t
ULONG;
144typedef uint32_t
DWORD;
145typedef struct _RUNTIME_FUNCTION {
149} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
157static const int kMaxFunctionLength = ((1 << 18) - 1) << 2;
159static constexpr int kDefaultNumberOfUnwindCodeWords = 1;
160static constexpr int kMaxExceptionThunkSize = 16;
161static constexpr int kFunctionLengthShiftSize = 2;
162static constexpr int kFunctionLengthMask = (1 << kFunctionLengthShiftSize) - 1;
165inline uint8_t MakeOpSaveFpLrX(
int pre_index_offset) {
168 ASSERT(pre_index_offset <= -8);
169 ASSERT(pre_index_offset >= -512);
170 constexpr int kShiftSize = 3;
171 constexpr int kShiftMask = (1 << kShiftSize) - 1;
172 ASSERT((pre_index_offset & kShiftMask) == 0);
175 int encoded_value = (-pre_index_offset >> kShiftSize) - 1;
176 return OpSaveFpLrX | encoded_value;
179template <
int kNumberOfUnwindCodeWords = kDefaultNumberOfUnwindCodeWords>
181 UNWIND_INFO unwind_info;
182 UNWIND_CODE unwind_codes[kNumberOfUnwindCodeWords];
185 memset(&unwind_info, 0,
sizeof(UNWIND_INFO));
187 unwind_info.CodeWords = kNumberOfUnwindCodeWords;
200 static_assert(kNumberOfUnwindCodeWords >= 1);
201 uword kCallerSPOffset = -16;
202 unwind_codes[0] = Combine8BitUnwindCodes(
203 OpSetFp, MakeOpSaveFpLrX(kCallerSPOffset), OpEnd);
206 for (
int i = 1; i < kNumberOfUnwindCodeWords; ++i) {
207 unwind_codes[i] = Combine8BitUnwindCodes();
212static const uint32_t kDefaultRuntimeFunctionCount = 1;
213static constexpr uint32_t kUnwindingRecordMagic = 0xAABBCCEE;
215struct CodeRangeUnwindingRecord {
218 uint32_t runtime_function_count;
219 UnwindData<> unwind_info;
220 uint32_t exception_handler;
226 UnwindData<> unwind_info1;
231 RUNTIME_FUNCTION runtime_function[kDefaultRuntimeFunctionCount];