include: Add some public exception handling structures.

This commit is contained in:
Alexandre Julliard 2024-02-13 14:49:47 +01:00
parent 0b441c4c8f
commit b9a985a677
5 changed files with 210 additions and 216 deletions

View file

@ -37,18 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh);
WINE_DECLARE_DEBUG_CHANNEL(relay); WINE_DECLARE_DEBUG_CHANNEL(relay);
WINE_DECLARE_DEBUG_CHANNEL(threadname); WINE_DECLARE_DEBUG_CHANNEL(threadname);
typedef struct _SCOPE_TABLE
{
ULONG Count;
struct
{
ULONG BeginAddress;
ULONG EndAddress;
ULONG HandlerAddress;
ULONG JumpTarget;
} ScopeRecord[1];
} SCOPE_TABLE, *PSCOPE_TABLE;
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */ /* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
struct MSVCRT_JUMP_BUFFER struct MSVCRT_JUMP_BUFFER

View file

@ -39,18 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh);
WINE_DECLARE_DEBUG_CHANNEL(relay); WINE_DECLARE_DEBUG_CHANNEL(relay);
WINE_DECLARE_DEBUG_CHANNEL(threadname); WINE_DECLARE_DEBUG_CHANNEL(threadname);
typedef struct _SCOPE_TABLE
{
ULONG Count;
struct
{
ULONG BeginAddress;
ULONG EndAddress;
ULONG HandlerAddress;
ULONG JumpTarget;
} ScopeRecord[1];
} SCOPE_TABLE, *PSCOPE_TABLE;
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */ /* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
struct MSVCRT_JUMP_BUFFER struct MSVCRT_JUMP_BUFFER
@ -600,16 +588,6 @@ __ASM_GLOBAL_FUNC( KiUserCallbackDispatcher,
* Definitions for Win32 unwind tables * Definitions for Win32 unwind tables
*/ */
struct unwind_info
{
DWORD function_length : 18;
DWORD version : 2;
DWORD x : 1;
DWORD e : 1;
DWORD epilog : 5;
DWORD codes : 5;
};
struct unwind_info_ext struct unwind_info_ext
{ {
WORD epilog; WORD epilog;
@ -960,16 +938,16 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *func, static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *func,
CONTEXT *context, PVOID *handler_data, KNONVOLATILE_CONTEXT_POINTERS *ptrs ) CONTEXT *context, PVOID *handler_data, KNONVOLATILE_CONTEXT_POINTERS *ptrs )
{ {
struct unwind_info *info; IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA *info;
struct unwind_info_epilog *info_epilog; struct unwind_info_epilog *info_epilog;
unsigned int i, codes, epilogs, len, offset; unsigned int i, codes, epilogs, len, offset;
void *data; void *data;
BYTE *end; BYTE *end;
info = (struct unwind_info *)((char *)base + func->UnwindData); info = (IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA *)((char *)base + func->UnwindData);
data = info + 1; data = info + 1;
epilogs = info->epilog; epilogs = info->EpilogCount;
codes = info->codes; codes = info->CodeWords;
if (!codes && !epilogs) if (!codes && !epilogs)
{ {
struct unwind_info_ext *infoex = data; struct unwind_info_ext *infoex = data;
@ -978,14 +956,15 @@ static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *f
data = infoex + 1; data = infoex + 1;
} }
info_epilog = data; info_epilog = data;
if (!info->e) data = info_epilog + epilogs; if (!info->EpilogInHeader) data = info_epilog + epilogs;
offset = ((pc - base) - func->BeginAddress) / 4; offset = ((pc - base) - func->BeginAddress) / 4;
end = (BYTE *)data + codes * 4; end = (BYTE *)data + codes * 4;
TRACE( "function %I64x-%I64x: len=%#x ver=%u X=%u E=%u epilogs=%u codes=%u\n", TRACE( "function %I64x-%I64x: len=%#x ver=%u X=%u E=%u epilogs=%u codes=%u\n",
base + func->BeginAddress, base + func->BeginAddress + info->function_length * 4, base + func->BeginAddress, base + func->BeginAddress + info->FunctionLength * 4,
info->function_length, info->version, info->x, info->e, epilogs, codes * 4 ); info->FunctionLength, info->Version, info->ExceptionDataPresent, info->EpilogInHeader,
epilogs, codes * 4 );
/* check for prolog */ /* check for prolog */
if (offset < codes * 4) if (offset < codes * 4)
@ -999,7 +978,7 @@ static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *f
} }
/* check for epilog */ /* check for epilog */
if (!info->e) if (!info->EpilogInHeader)
{ {
for (i = 0; i < epilogs; i++) for (i = 0; i < epilogs; i++)
{ {
@ -1016,13 +995,13 @@ static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *f
} }
} }
} }
else if (info->function_length - offset <= codes * 4 - epilogs) else if (info->FunctionLength - offset <= codes * 4 - epilogs)
{ {
BYTE *ptr = (BYTE *)data + epilogs; BYTE *ptr = (BYTE *)data + epilogs;
len = get_sequence_len( ptr, end ) + 1; len = get_sequence_len( ptr, end ) + 1;
if (offset >= info->function_length - len) if (offset >= info->FunctionLength - len)
{ {
process_unwind_codes( ptr, end, context, ptrs, offset - (info->function_length - len) ); process_unwind_codes( ptr, end, context, ptrs, offset - (info->FunctionLength - len) );
return NULL; return NULL;
} }
} }
@ -1030,7 +1009,7 @@ static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *f
process_unwind_codes( data, end, context, ptrs, 0 ); process_unwind_codes( data, end, context, ptrs, 0 );
/* get handler since we are inside the main code */ /* get handler since we are inside the main code */
if (info->x) if (info->ExceptionDataPresent)
{ {
DWORD *handler_rva = (DWORD *)data + codes; DWORD *handler_rva = (DWORD *)data + codes;
*handler_data = handler_rva + 1; *handler_data = handler_rva + 1;

View file

@ -38,18 +38,6 @@ WINE_DECLARE_DEBUG_CHANNEL(seh);
WINE_DECLARE_DEBUG_CHANNEL(relay); WINE_DECLARE_DEBUG_CHANNEL(relay);
WINE_DECLARE_DEBUG_CHANNEL(threadname); WINE_DECLARE_DEBUG_CHANNEL(threadname);
typedef struct _SCOPE_TABLE
{
ULONG Count;
struct
{
ULONG BeginAddress;
ULONG EndAddress;
ULONG HandlerAddress;
ULONG JumpTarget;
} ScopeRecord[1];
} SCOPE_TABLE, *PSCOPE_TABLE;
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */ /* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
struct MSVCRT_JUMP_BUFFER struct MSVCRT_JUMP_BUFFER

View file

@ -110,18 +110,6 @@ static void (WINAPI *pRtlGetUnloadEventTraceEx)(ULONG **element_size, ULONG **el
#endif #endif
#if defined(__x86_64__) #if defined(__x86_64__)
typedef struct
{
ULONG Count;
struct
{
ULONG BeginAddress;
ULONG EndAddress;
ULONG HandlerAddress;
ULONG JumpTarget;
} ScopeRecord[1];
} SCOPE_TABLE;
typedef struct _SETJMP_FLOAT128 typedef struct _SETJMP_FLOAT128
{ {
unsigned __int64 DECLSPEC_ALIGN(16) Part[2]; unsigned __int64 DECLSPEC_ALIGN(16) Part[2];
@ -9653,23 +9641,13 @@ static void test_KiUserCallbackDispatcher(void)
VirtualProtect( pKiUserCallbackDispatcher, sizeof(saved_code), old_protect, &old_protect ); VirtualProtect( pKiUserCallbackDispatcher, sizeof(saved_code), old_protect, &old_protect );
} }
struct unwind_info
{
DWORD function_length : 18;
DWORD version : 2;
DWORD x : 1;
DWORD e : 1;
DWORD epilog : 5;
DWORD codes : 5;
};
static void run_exception_test(void *handler, const void* context, static void run_exception_test(void *handler, const void* context,
const void *code, unsigned int code_size, const void *code, unsigned int code_size,
unsigned int func2_offset, DWORD access, DWORD handler_flags) unsigned int func2_offset, DWORD access, DWORD handler_flags)
{ {
DWORD buf[14]; DWORD buf[14];
RUNTIME_FUNCTION runtime_func[2]; RUNTIME_FUNCTION runtime_func[2];
struct unwind_info unwind; IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA unwind;
void (*func)(void) = code_mem; void (*func)(void) = code_mem;
DWORD oldaccess, oldaccess2; DWORD oldaccess, oldaccess2;
@ -9678,19 +9656,19 @@ static void run_exception_test(void *handler, const void* context,
runtime_func[1].BeginAddress = func2_offset; runtime_func[1].BeginAddress = func2_offset;
runtime_func[1].UnwindData = 0x1014; runtime_func[1].UnwindData = 0x1014;
unwind.function_length = func2_offset / 4; unwind.FunctionLength = func2_offset / 4;
unwind.version = 0; unwind.Version = 0;
unwind.x = 1; unwind.ExceptionDataPresent = 1;
unwind.e = 1; unwind.EpilogInHeader = 1;
unwind.epilog = 1; unwind.EpilogCount = 1;
unwind.codes = 1; unwind.CodeWords = 1;
buf[0] = *(DWORD *)&unwind; buf[0] = unwind.HeaderData;
buf[1] = 0xe3e481e1; /* mov x29,sp; stp r29,lr,[sp,-#0x10]!; end; nop */ buf[1] = 0xe3e481e1; /* mov x29,sp; stp r29,lr,[sp,-#0x10]!; end; nop */
buf[2] = 0x1028; buf[2] = 0x1028;
*(const void **)&buf[3] = context; *(const void **)&buf[3] = context;
unwind.function_length = (code_size - func2_offset) / 4; unwind.FunctionLength = (code_size - func2_offset) / 4;
buf[5] = *(DWORD *)&unwind; buf[5] = unwind.HeaderData;
buf[6] = 0xe3e481e1; /* mov x29,sp; stp r29,lr,[sp,-#0x10]!; end; nop */ buf[6] = 0xe3e481e1; /* mov x29,sp; stp r29,lr,[sp,-#0x10]!; end; nop */
buf[7] = 0x1028; buf[7] = 0x1028;
*(const void **)&buf[8] = context; *(const void **)&buf[8] = context;

View file

@ -1255,12 +1255,24 @@ typedef struct _XSAVE_FORMAT {
/* x86-64 context definitions */ /* x86-64 context definitions */
typedef struct _AMD64_RUNTIME_FUNCTION typedef struct IMAGE_AMD64_RUNTIME_FUNCTION_ENTRY
{ {
DWORD BeginAddress; DWORD BeginAddress;
DWORD EndAddress; DWORD EndAddress;
DWORD UnwindData; DWORD UnwindData;
} AMD64_RUNTIME_FUNCTION; } IMAGE_AMD64_RUNTIME_FUNCTION_ENTRY;
typedef struct _SCOPE_TABLE_AMD64
{
DWORD Count;
struct
{
DWORD BeginAddress;
DWORD EndAddress;
DWORD HandlerAddress;
DWORD JumpTarget;
} ScopeRecord[1];
} SCOPE_TABLE_AMD64, *PSCOPE_TABLE_AMD64;
#define CONTEXT_AMD64 0x00100000 #define CONTEXT_AMD64 0x00100000
@ -1374,7 +1386,8 @@ typedef struct DECLSPEC_ALIGN(16) _AMD64_CONTEXT {
#define CONTEXT_ALL CONTEXT_AMD64_ALL #define CONTEXT_ALL CONTEXT_AMD64_ALL
typedef AMD64_CONTEXT CONTEXT, *PCONTEXT; typedef AMD64_CONTEXT CONTEXT, *PCONTEXT;
typedef AMD64_RUNTIME_FUNCTION RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; typedef IMAGE_AMD64_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
typedef SCOPE_TABLE_AMD64 SCOPE_TABLE, *PSCOPE_TABLE;
typedef struct _KNONVOLATILE_CONTEXT_POINTERS typedef struct _KNONVOLATILE_CONTEXT_POINTERS
{ {
@ -1545,6 +1558,18 @@ typedef struct _IMAGE_ARM_RUNTIME_FUNCTION
} DUMMYUNIONNAME; } DUMMYUNIONNAME;
} IMAGE_ARM_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ARM_RUNTIME_FUNCTION_ENTRY; } IMAGE_ARM_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ARM_RUNTIME_FUNCTION_ENTRY;
typedef struct _SCOPE_TABLE_ARM
{
DWORD Count;
struct
{
DWORD BeginAddress;
DWORD EndAddress;
DWORD HandlerAddress;
DWORD JumpTarget;
} ScopeRecord[1];
} SCOPE_TABLE_ARM, *PSCOPE_TABLE_ARM;
typedef struct _ARM_NEON128 typedef struct _ARM_NEON128
{ {
ULONGLONG Low; ULONGLONG Low;
@ -1600,6 +1625,7 @@ typedef struct _ARM_CONTEXT
#define CONTEXT_ALL CONTEXT_ARM_ALL #define CONTEXT_ALL CONTEXT_ARM_ALL
typedef IMAGE_ARM_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; typedef IMAGE_ARM_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
typedef SCOPE_TABLE_ARM SCOPE_TABLE, *PSCOPE_TABLE;
typedef ARM_NEON128 NEON128, *PNEON128; typedef ARM_NEON128 NEON128, *PNEON128;
typedef ARM_CONTEXT CONTEXT, *PCONTEXT; typedef ARM_CONTEXT CONTEXT, *PCONTEXT;
@ -1635,6 +1661,9 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS
#define CONTEXT_ARM64_FULL (CONTEXT_ARM64_CONTROL | CONTEXT_ARM64_INTEGER | CONTEXT_ARM64_FLOATING_POINT) #define CONTEXT_ARM64_FULL (CONTEXT_ARM64_CONTROL | CONTEXT_ARM64_INTEGER | CONTEXT_ARM64_FLOATING_POINT)
#define CONTEXT_ARM64_ALL (CONTEXT_ARM64_FULL | CONTEXT_ARM64_DEBUG_REGISTERS | CONTEXT_ARM64_X18) #define CONTEXT_ARM64_ALL (CONTEXT_ARM64_FULL | CONTEXT_ARM64_DEBUG_REGISTERS | CONTEXT_ARM64_X18)
#define CONTEXT_ARM64_UNWOUND_TO_CALL 0x20000000
#define CONTEXT_ARM64_RET_TO_GUEST 0x04000000
#define CONTEXT_UNWOUND_TO_CALL 0x20000000 #define CONTEXT_UNWOUND_TO_CALL 0x20000000
#define ARM64_MAX_BREAKPOINTS 8 #define ARM64_MAX_BREAKPOINTS 8
@ -1659,8 +1688,73 @@ typedef struct _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY
} DUMMYUNIONNAME; } DUMMYUNIONNAME;
} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY; } IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY;
typedef union IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA
{
DWORD HeaderData;
struct
{
DWORD FunctionLength : 18;
DWORD Version : 2;
DWORD ExceptionDataPresent : 1;
DWORD EpilogInHeader : 1;
DWORD EpilogCount : 5;
DWORD CodeWords : 5;
} DUMMYSTRUCTNAME;
} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA;
typedef enum ARM64_FNPDATA_FLAGS
{
PdataRefToFullXdata = 0,
PdataPackedUnwindFunction = 1,
PdataPackedUnwindFragment = 2,
} ARM64_FNPDATA_FLAGS;
typedef enum ARM64_FNPDATA_CR
{
PdataCrUnchained = 0,
PdataCrUnchainedSavedLr = 1,
PdataCrChainedWithPac = 2,
PdataCrChained = 3,
} ARM64_FNPDATA_CR;
typedef IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY ARM64_RUNTIME_FUNCTION, *PARM64_RUNTIME_FUNCTION; typedef IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY ARM64_RUNTIME_FUNCTION, *PARM64_RUNTIME_FUNCTION;
typedef struct _SCOPE_TABLE_ARM64
{
DWORD Count;
struct
{
DWORD BeginAddress;
DWORD EndAddress;
DWORD HandlerAddress;
DWORD JumpTarget;
} ScopeRecord[1];
} SCOPE_TABLE_ARM64, *PSCOPE_TABLE_ARM64;
typedef struct _KNONVOLATILE_CONTEXT_POINTERS_ARM64
{
PDWORD64 X19;
PDWORD64 X20;
PDWORD64 X21;
PDWORD64 X22;
PDWORD64 X23;
PDWORD64 X24;
PDWORD64 X25;
PDWORD64 X26;
PDWORD64 X27;
PDWORD64 X28;
PDWORD64 Fp;
PDWORD64 Lr;
PDWORD64 D8;
PDWORD64 D9;
PDWORD64 D10;
PDWORD64 D11;
PDWORD64 D12;
PDWORD64 D13;
PDWORD64 D14;
PDWORD64 D15;
} KNONVOLATILE_CONTEXT_POINTERS_ARM64, *PKNONVOLATILE_CONTEXT_POINTERS_ARM64;
typedef union _ARM64_NT_NEON128 typedef union _ARM64_NT_NEON128
{ {
struct struct
@ -1845,34 +1939,15 @@ typedef struct DECLSPEC_ALIGN(16) _ARM64EC_NT_CONTEXT
#define CONTEXT_DEBUG_REGISTERS CONTEXT_ARM64_DEBUG_REGISTERS #define CONTEXT_DEBUG_REGISTERS CONTEXT_ARM64_DEBUG_REGISTERS
#define CONTEXT_FULL CONTEXT_ARM64_FULL #define CONTEXT_FULL CONTEXT_ARM64_FULL
#define CONTEXT_ALL CONTEXT_ARM64_ALL #define CONTEXT_ALL CONTEXT_ARM64_ALL
#define CONTEXT_RET_TO_GUEST CONTEXT_ARM64_RET_TO_GUEST
typedef IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; typedef IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
typedef SCOPE_TABLE_ARM64 SCOPE_TABLE, *PSCOPE_TABLE;
typedef KNONVOLATILE_CONTEXT_POINTERS_ARM64 KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
typedef ARM64_NT_NEON128 NEON128, *PNEON128; typedef ARM64_NT_NEON128 NEON128, *PNEON128;
typedef ARM64_NT_CONTEXT CONTEXT, *PCONTEXT; typedef ARM64_NT_CONTEXT CONTEXT, *PCONTEXT;
typedef struct _KNONVOLATILE_CONTEXT_POINTERS #define _DISPATCHER_CONTEXT_ARM64 _DISPATCHER_CONTEXT
{
PDWORD64 X19;
PDWORD64 X20;
PDWORD64 X21;
PDWORD64 X22;
PDWORD64 X23;
PDWORD64 X24;
PDWORD64 X25;
PDWORD64 X26;
PDWORD64 X27;
PDWORD64 X28;
PDWORD64 Fp;
PDWORD64 Lr;
PDWORD64 D8;
PDWORD64 D9;
PDWORD64 D10;
PDWORD64 D11;
PDWORD64 D12;
PDWORD64 D13;
PDWORD64 D14;
PDWORD64 D15;
} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
#endif /* __aarch64__ */ #endif /* __aarch64__ */
@ -1920,44 +1995,63 @@ struct _EXCEPTION_RECORD;
typedef EXCEPTION_DISPOSITION WINAPI EXCEPTION_ROUTINE(struct _EXCEPTION_RECORD*,PVOID,CONTEXT*,PVOID); typedef EXCEPTION_DISPOSITION WINAPI EXCEPTION_ROUTINE(struct _EXCEPTION_RECORD*,PVOID,CONTEXT*,PVOID);
typedef EXCEPTION_ROUTINE *PEXCEPTION_ROUTINE; typedef EXCEPTION_ROUTINE *PEXCEPTION_ROUTINE;
typedef struct _DISPATCHER_CONTEXT_ARM64
{
ULONG_PTR ControlPc;
ULONG_PTR ImageBase;
PARM64_RUNTIME_FUNCTION FunctionEntry;
ULONG_PTR EstablisherFrame;
ULONG_PTR TargetPc;
PARM64_NT_CONTEXT ContextRecord;
PEXCEPTION_ROUTINE LanguageHandler;
PVOID HandlerData;
struct _UNWIND_HISTORY_TABLE *HistoryTable;
DWORD ScopeIndex;
BOOLEAN ControlPcIsUnwound;
PBYTE NonVolatileRegisters;
} DISPATCHER_CONTEXT_ARM64, *PDISPATCHER_CONTEXT_ARM64;
#ifdef __x86_64__ #ifdef __x86_64__
#define UNWIND_HISTORY_TABLE_SIZE 12
typedef struct _UNWIND_HISTORY_TABLE_ENTRY
{
ULONG64 ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
#define UNWIND_HISTORY_TABLE_NONE 0
#define UNWIND_HISTORY_TABLE_GLOBAL 1
#define UNWIND_HISTORY_TABLE_LOCAL 2
typedef struct _UNWIND_HISTORY_TABLE
{
ULONG Count;
UCHAR Search;
ULONG64 LowAddress;
ULONG64 HighAddress;
UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
typedef struct _DISPATCHER_CONTEXT typedef struct _DISPATCHER_CONTEXT
{ {
ULONG64 ControlPc; ULONG64 ControlPc;
ULONG64 ImageBase; ULONG64 ImageBase;
PRUNTIME_FUNCTION FunctionEntry; PRUNTIME_FUNCTION FunctionEntry;
ULONG64 EstablisherFrame; ULONG64 EstablisherFrame;
ULONG64 TargetIp; ULONG64 TargetIp;
PCONTEXT ContextRecord; PCONTEXT ContextRecord;
PEXCEPTION_ROUTINE LanguageHandler; PEXCEPTION_ROUTINE LanguageHandler;
PVOID HandlerData; PVOID HandlerData;
PUNWIND_HISTORY_TABLE HistoryTable; struct _UNWIND_HISTORY_TABLE *HistoryTable;
DWORD ScopeIndex; DWORD ScopeIndex;
DWORD Fill0; DWORD Fill0;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; } DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
#ifdef __arm64ec__
typedef struct _DISPATCHER_CONTEXT_ARM64EC
{
ULONG64 ControlPc;
ULONG64 ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
ULONG64 EstablisherFrame;
union
{
ULONG64 TargetIp;
ULONG64 TargetPc;
} DUMMYUNIONNAME;
PCONTEXT ContextRecord;
PEXCEPTION_ROUTINE LanguageHandler;
PVOID HandlerData;
struct _UNWIND_HISTORY_TABLE *HistoryTable;
DWORD ScopeIndex;
BOOLEAN ControlPcIsUnwound;
PBYTE NonVolatileRegisters;
} DISPATCHER_CONTEXT_ARM64EC, *PDISPATCHER_CONTEXT_ARM64EC;
#endif
typedef LONG (CALLBACK *PEXCEPTION_FILTER)(struct _EXCEPTION_POINTERS*,PVOID); typedef LONG (CALLBACK *PEXCEPTION_FILTER)(struct _EXCEPTION_POINTERS*,PVOID);
typedef void (CALLBACK *PTERMINATION_HANDLER)(BOOLEAN,PVOID); typedef void (CALLBACK *PTERMINATION_HANDLER)(BOOLEAN,PVOID);
@ -1968,41 +2062,21 @@ typedef void (CALLBACK *PTERMINATION_HANDLER)(BOOLEAN,PVOID);
#elif defined(__arm__) #elif defined(__arm__)
#define UNWIND_HISTORY_TABLE_SIZE 12
typedef struct _UNWIND_HISTORY_TABLE_ENTRY
{
DWORD ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
typedef struct _UNWIND_HISTORY_TABLE
{
DWORD Count;
BYTE LocalHint;
BYTE GlobalHint;
BYTE Search;
BYTE Once;
DWORD LowAddress;
DWORD HighAddress;
UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
typedef struct _DISPATCHER_CONTEXT typedef struct _DISPATCHER_CONTEXT
{ {
DWORD ControlPc; DWORD ControlPc;
DWORD ImageBase; DWORD ImageBase;
PRUNTIME_FUNCTION FunctionEntry; PRUNTIME_FUNCTION FunctionEntry;
DWORD EstablisherFrame; DWORD EstablisherFrame;
DWORD TargetPc; DWORD TargetPc;
PCONTEXT ContextRecord; PCONTEXT ContextRecord;
PEXCEPTION_ROUTINE LanguageHandler; PEXCEPTION_ROUTINE LanguageHandler;
PVOID HandlerData; PVOID HandlerData;
PUNWIND_HISTORY_TABLE HistoryTable; struct _UNWIND_HISTORY_TABLE *HistoryTable;
DWORD ScopeIndex; DWORD ScopeIndex;
BOOLEAN ControlPcIsUnwound; BOOLEAN ControlPcIsUnwound;
PBYTE NonVolatileRegisters; PBYTE NonVolatileRegisters;
DWORD Reserved; DWORD Reserved;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; } DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
typedef LONG (CALLBACK *PEXCEPTION_FILTER)(struct _EXCEPTION_POINTERS*,DWORD); typedef LONG (CALLBACK *PEXCEPTION_FILTER)(struct _EXCEPTION_POINTERS*,DWORD);
@ -2014,41 +2088,8 @@ typedef void (CALLBACK *PTERMINATION_HANDLER)(BOOLEAN,DWORD);
#elif defined(__aarch64__) #elif defined(__aarch64__)
#define UNWIND_HISTORY_TABLE_SIZE 12 #undef _DISPATCHER_CONTEXT_ARM64
typedef DISPATCHER_CONTEXT_ARM64 DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
typedef struct _UNWIND_HISTORY_TABLE_ENTRY
{
DWORD64 ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
typedef struct _UNWIND_HISTORY_TABLE
{
DWORD Count;
BYTE LocalHint;
BYTE GlobalHint;
BYTE Search;
BYTE Once;
DWORD64 LowAddress;
DWORD64 HighAddress;
UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
typedef struct _DISPATCHER_CONTEXT
{
ULONG_PTR ControlPc;
ULONG_PTR ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
ULONG_PTR EstablisherFrame;
ULONG_PTR TargetPc;
PCONTEXT ContextRecord;
PEXCEPTION_ROUTINE LanguageHandler;
PVOID HandlerData;
PUNWIND_HISTORY_TABLE HistoryTable;
DWORD ScopeIndex;
BOOLEAN ControlPcIsUnwound;
PBYTE NonVolatileRegisters;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
typedef LONG (CALLBACK *PEXCEPTION_FILTER)(struct _EXCEPTION_POINTERS*,DWORD64); typedef LONG (CALLBACK *PEXCEPTION_FILTER)(struct _EXCEPTION_POINTERS*,DWORD64);
typedef void (CALLBACK *PTERMINATION_HANDLER)(BOOLEAN,DWORD64); typedef void (CALLBACK *PTERMINATION_HANDLER)(BOOLEAN,DWORD64);
@ -2065,6 +2106,26 @@ NTSYSAPI void NTAPI RtlUnwind(void*,void*,struct _EXCEPTION_RECORD*,void*);
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
#define UNWIND_HISTORY_TABLE_SIZE 12
typedef struct _UNWIND_HISTORY_TABLE_ENTRY
{
ULONG_PTR ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
typedef struct _UNWIND_HISTORY_TABLE
{
DWORD Count;
BYTE LocalHint;
BYTE GlobalHint;
BYTE Search;
BYTE Once;
ULONG_PTR LowAddress;
ULONG_PTR HighAddress;
UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
typedef PRUNTIME_FUNCTION (CALLBACK *PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD_PTR,PVOID); typedef PRUNTIME_FUNCTION (CALLBACK *PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD_PTR,PVOID);
NTSYSAPI BOOLEAN CDECL RtlAddFunctionTable(RUNTIME_FUNCTION*,DWORD,DWORD_PTR); NTSYSAPI BOOLEAN CDECL RtlAddFunctionTable(RUNTIME_FUNCTION*,DWORD,DWORD_PTR);