dart-sdk/runtime/platform/unwinding_records.h
Alexander Aprelev 3a668dcf03 [vm/win/aot] Provide unwinding information for Windows AOT snapshots.
Fixes https://github.com/dart-lang/sdk/issues/52045
TEST=ffi_induce_a_crash_test

Change-Id: Ic047df10732d6ff8cf695ce098d80ec3a098dbf9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/302380
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
2023-05-11 03:14:27 +00:00

95 lines
2.7 KiB
C++

// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Class for patching compiled code.
#ifndef RUNTIME_PLATFORM_UNWINDING_RECORDS_H_
#define RUNTIME_PLATFORM_UNWINDING_RECORDS_H_
#include "platform/allocation.h"
namespace dart {
class UnwindingRecordsPlatform : public AllStatic {
public:
static void Init();
static void Cleanup();
static intptr_t SizeInBytes();
static void RegisterExecutableMemory(void* start,
intptr_t size,
void** pp_dynamic_table);
static void UnregisterDynamicTable(void* p_dynamic_table);
static void* GetAddGrowableFunctionTableFunc();
static void* GetDeleteGrowableFunctionTableFunc();
};
#if defined(DART_HOST_OS_WINDOWS) && defined(TARGET_ARCH_X64)
#pragma pack(push, 1)
//
// Refer to https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64
//
typedef unsigned char UBYTE;
typedef union _UNWIND_CODE {
struct {
UBYTE CodeOffset;
UBYTE UnwindOp : 4;
UBYTE OpInfo : 4;
};
USHORT FrameOffset;
} UNWIND_CODE, *PUNWIND_CODE;
typedef struct _UNWIND_INFO {
UBYTE Version : 3;
UBYTE Flags : 5;
UBYTE SizeOfProlog;
UBYTE CountOfCodes;
UBYTE FrameRegister : 4;
UBYTE FrameOffset : 4;
UNWIND_CODE UnwindCode[2];
} UNWIND_INFO, *PUNWIND_INFO;
static constexpr int kPushRbpInstructionLength = 1;
static const int kMovRbpRspInstructionLength = 3;
static constexpr int kRbpPrefixLength =
kPushRbpInstructionLength + kMovRbpRspInstructionLength;
static constexpr int kRBP = 5;
struct GeneratedCodeUnwindInfo {
UNWIND_INFO unwind_info;
GeneratedCodeUnwindInfo() {
unwind_info.Version = 1;
unwind_info.Flags = UNW_FLAG_NHANDLER;
unwind_info.SizeOfProlog = kRbpPrefixLength;
unwind_info.CountOfCodes = 2;
unwind_info.FrameRegister = kRBP;
unwind_info.FrameOffset = 0;
unwind_info.UnwindCode[0].CodeOffset = kRbpPrefixLength;
unwind_info.UnwindCode[0].UnwindOp = 3; // UWOP_SET_FPREG
unwind_info.UnwindCode[0].OpInfo = 0;
unwind_info.UnwindCode[1].CodeOffset = kPushRbpInstructionLength;
unwind_info.UnwindCode[1].UnwindOp = 0; // UWOP_PUSH_NONVOL
unwind_info.UnwindCode[1].OpInfo = kRBP;
}
};
struct CodeRangeUnwindingRecord {
void* dynamic_table;
uint32_t runtime_function_count;
GeneratedCodeUnwindInfo unwind_info;
intptr_t exception_handler;
RUNTIME_FUNCTION runtime_function[1];
};
#pragma pack(pop)
#endif // defined(DART_HOST_OS_WINDOWS) && defined(TARGET_ARCH_X64)
} // namespace dart
#endif // RUNTIME_PLATFORM_UNWINDING_RECORDS_H_