mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[NTOS:KE/x64] Fix unwinding in KiUserApcDispatcher
This adds a MACHINE_FRAME to the user mode APC dispatcher stack frame.
This commit is contained in:
parent
91948dea80
commit
29721ac552
3 changed files with 47 additions and 6 deletions
|
@ -33,6 +33,32 @@ PUBLIC LdrInitializeThunk
|
|||
|
||||
PUBLIC KiUserApcDispatcher
|
||||
.PROC KiUserApcDispatcher
|
||||
|
||||
/* The stack is set up with a UAPC_FRAME, which ends with a MACHINE_FRAME */
|
||||
.PUSHFRAME
|
||||
.ALLOCSTACK CONTEXT_FRAME_LENGTH
|
||||
|
||||
/* The stack points to a CONTEXT structure.
|
||||
Create unwind ops for all nonvolatile registers */
|
||||
.SAVEREG rbx, CxRbx
|
||||
.SAVEREG rbp, CxRbp
|
||||
.SAVEREG rsi, CxRsi
|
||||
.SAVEREG rdi, CxRdi
|
||||
.SAVEREG r12, CxR12
|
||||
.SAVEREG r13, CxR13
|
||||
.SAVEREG r14, CxR14
|
||||
.SAVEREG r15, CxR15
|
||||
.SAVEXMM128 xmm6, CxXmm6
|
||||
.SAVEXMM128 xmm7, CxXmm7
|
||||
.SAVEXMM128 xmm8, CxXmm8
|
||||
.SAVEXMM128 xmm9, CxXmm9
|
||||
.SAVEXMM128 xmm10, CxXmm10
|
||||
.SAVEXMM128 xmm11, CxXmm11
|
||||
.SAVEXMM128 xmm12, CxXmm12
|
||||
.SAVEXMM128 xmm13, CxXmm13
|
||||
.SAVEXMM128 xmm14, CxXmm14
|
||||
.SAVEXMM128 xmm15, CxXmm15
|
||||
|
||||
.endprolog
|
||||
/* We enter with a 16 byte aligned stack */
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
*
|
||||
* \brief
|
||||
* Prepares the current trap frame (which must have come from user mode)
|
||||
* with the ntdll.KiUserApcDispatcher entrypoint, copying a CONTEXT
|
||||
* record with the context from the old trap frame to the threads user
|
||||
* with the ntdll.KiUserApcDispatcher entrypoint, copying a UAPC_FRAME
|
||||
* structure with the context from the old trap frame to the threads user
|
||||
* mode stack.
|
||||
*
|
||||
* \param ExceptionFrame - Pointer to the Exception Frame
|
||||
|
@ -53,20 +53,22 @@ KiInitializeUserApc(
|
|||
_In_ PVOID SystemArgument1,
|
||||
_In_ PVOID SystemArgument2)
|
||||
{
|
||||
PUAPC_FRAME ApcFrame;
|
||||
PCONTEXT Context;
|
||||
EXCEPTION_RECORD ExceptionRecord;
|
||||
|
||||
/* Sanity check, that the trap frame is from user mode */
|
||||
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
|
||||
|
||||
/* Align the user tack to 16 bytes and allocate space for a CONTEXT structure */
|
||||
Context = (PCONTEXT)ALIGN_DOWN_POINTER_BY(TrapFrame->Rsp, 16) - 1;
|
||||
/* Allocate a 16 byte aligned UAPC_FRAME structure on the user stack */
|
||||
ApcFrame = (PUAPC_FRAME)ALIGN_DOWN_POINTER_BY(TrapFrame->Rsp - sizeof(*ApcFrame), 16);
|
||||
Context = &ApcFrame->Context;
|
||||
|
||||
/* Protect with SEH */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Probe the context */
|
||||
ProbeForWrite(Context, sizeof(CONTEXT), 16);
|
||||
/* Probe the user mode APC frame */
|
||||
ProbeForWrite(ApcFrame, sizeof(*ApcFrame), 16);
|
||||
|
||||
/* Convert the current trap frame to a context */
|
||||
Context->ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||
|
@ -77,6 +79,10 @@ KiInitializeUserApc(
|
|||
Context->P2Home = (ULONG64)SystemArgument1;
|
||||
Context->P3Home = (ULONG64)SystemArgument2;
|
||||
Context->P4Home = (ULONG64)NormalRoutine;
|
||||
|
||||
/* Set up the machine frame for unwinding */
|
||||
ApcFrame->MachineFrame.Rip = TrapFrame->Rip;
|
||||
ApcFrame->MachineFrame.Rsp = TrapFrame->Rsp;
|
||||
}
|
||||
_SEH2_EXCEPT(ExceptionRecord = *_SEH2_GetExceptionInformation()->ExceptionRecord, EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
|
|
@ -1073,6 +1073,15 @@ typedef struct _UCALLOUT_FRAME
|
|||
MACHINE_FRAME MachineFrame;
|
||||
} UCALLOUT_FRAME, *PUCALLOUT_FRAME; // size = 0x0058
|
||||
|
||||
//
|
||||
// User side APC dispatcher frame
|
||||
//
|
||||
typedef struct _UAPC_FRAME
|
||||
{
|
||||
CONTEXT Context;
|
||||
MACHINE_FRAME MachineFrame;
|
||||
} UAPC_FRAME, *PUAPC_FRAME;
|
||||
|
||||
//
|
||||
// Stack frame layout for KiUserExceptionDispatcher
|
||||
// The name is totally made up
|
||||
|
|
Loading…
Reference in a new issue