mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
29721ac552
This adds a MACHINE_FRAME to the user mode APC dispatcher stack frame.
258 lines
5.6 KiB
ArmAsm
258 lines
5.6 KiB
ArmAsm
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* FILE: ntdll/dispatch/amd64/dispatch.S
|
|
* PURPOSE: Usermode dispatcher stubs
|
|
*
|
|
* PROGRAMMER: Timo kreuzer (timo.kreuzer@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <asm.inc>
|
|
#include <ksamd64.inc>
|
|
|
|
EXTERN NtContinue:PROC
|
|
EXTERN LdrpInit:PROC
|
|
EXTERN ZwCallbackReturn:PROC
|
|
EXTERN RtlRaiseStatus:PROC
|
|
|
|
.code
|
|
|
|
PUBLIC LdrInitializeThunk
|
|
.PROC LdrInitializeThunk
|
|
mov rbp, 0
|
|
.setframe rbp, 0
|
|
.endprolog
|
|
|
|
/* First parameter is the APC context */
|
|
mov rcx, r9
|
|
jmp LdrpInit
|
|
|
|
.ENDP
|
|
|
|
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 */
|
|
|
|
mov rcx, [rsp + CONTEXT_P1Home] /* NormalContext */
|
|
mov rdx, [rsp + CONTEXT_P2Home] /* SystemArgument1 */
|
|
mov r8, [rsp + CONTEXT_P3Home] /* SystemArgument2 */
|
|
lea r9, [rsp] /* Context */
|
|
call qword ptr [rsp + CONTEXT_P4Home] /* NormalRoutine */
|
|
|
|
/* NtContinue(Context, TRUE); */
|
|
lea rcx, [rsp]
|
|
mov dl, 1
|
|
call NtContinue
|
|
|
|
nop
|
|
int 3
|
|
.ENDP
|
|
|
|
|
|
PUBLIC KiRaiseUserExceptionDispatcher
|
|
.PROC KiRaiseUserExceptionDispatcher
|
|
.endprolog
|
|
int 3
|
|
|
|
.ENDP
|
|
|
|
PUBLIC KiUserCallbackDispatcher
|
|
.PROC KiUserCallbackDispatcher
|
|
|
|
/* The stack is set up with a UCALLOUT_FRAME */
|
|
/* The frame ends with a MACHINE_FRAME. */
|
|
.PUSHFRAME
|
|
|
|
/* This is for the Home space, Buffer, Length and ApiNumber */
|
|
.ALLOCSTACK (6 * 8)
|
|
.ENDPROLOG
|
|
|
|
#if DBG
|
|
/* We enter the function with a fully setup stack, so it must be aligned! */
|
|
test rsp, 15
|
|
jz AlignmentOk
|
|
int HEX(2C)
|
|
AlignmentOk:
|
|
#endif
|
|
|
|
/* Get the parameters from the callout frame */
|
|
mov rcx, [rsp + CkBuffer]
|
|
mov edx, [rsp + CkLength]
|
|
mov r8d, [rsp + CkApiNumber]
|
|
|
|
/* Get the callback table */
|
|
mov rax, gs:[TePeb]
|
|
mov r9, [rax + PeKernelCallbackTable]
|
|
|
|
/* Call the routine */
|
|
call qword ptr [r9 + r8 * 8]
|
|
|
|
/* Return from callback */
|
|
xor ecx, ecx
|
|
xor edx, edx
|
|
mov r8d, eax
|
|
call ZwCallbackReturn
|
|
|
|
/* Save callback return value */
|
|
mov esi, eax
|
|
|
|
/* Raise status */
|
|
StatusRaise:
|
|
mov ecx, esi
|
|
call RtlRaiseStatus
|
|
jmp StatusRaise
|
|
|
|
.ENDP
|
|
|
|
/*
|
|
BOOLEAN
|
|
NTAPI
|
|
RtlDispatchException(
|
|
_In_ PEXCEPTION_RECORD ExceptionRecord,
|
|
_In_ PCONTEXT ContextRecord);
|
|
*/
|
|
EXTERN RtlDispatchException:PROC
|
|
|
|
/*
|
|
NTSTATUS
|
|
NTAPI
|
|
ZwContinue(
|
|
_In_ PCONTEXT Context,
|
|
_In_ BOOLEAN TestAlert);
|
|
*/
|
|
EXTERN ZwContinue:PROC
|
|
|
|
/*
|
|
NTSTATUS
|
|
NTAPI
|
|
ZwRaiseException(
|
|
_In_ PEXCEPTION_RECORD ExceptionRecord,
|
|
_In_ PCONTEXT Context,
|
|
_In_ BOOLEAN SearchFrames);
|
|
*/
|
|
EXTERN ZwRaiseException:PROC
|
|
|
|
/*
|
|
VOID
|
|
NTAPI
|
|
RtlRaiseStatus(
|
|
_In_ PEXCEPTION_RECORD ExceptionRecord);
|
|
*/
|
|
EXTERN RtlRaiseException:PROC
|
|
|
|
/*
|
|
VOID
|
|
KiUserExceptionDispatcher(
|
|
CONTEXT ContextRecord<rcx>,
|
|
PEXCEPTION_RECORD ExceptionRecord<rdx>);
|
|
|
|
This function is called with the following stack layout:
|
|
CONTEXT ContextRecord <- RSP, RCX
|
|
EXCEPTION_RECORD ExceptionRecord <- RDX
|
|
ULONG64 Alignment
|
|
MACHINE_FRAME MachineFrame
|
|
*/
|
|
PUBLIC KiUserExceptionDispatcher
|
|
.PROC KiUserExceptionDispatcher
|
|
|
|
/* The stack is set up with a KUSER_EXCEPTION_STACK */
|
|
/* The frame ends with a MACHINE_FRAME. */
|
|
.PUSHFRAME
|
|
|
|
/* This is for the alignment, EXCEPTION_RECORD and CONTEXT */
|
|
.ALLOCSTACK 8 + EXCEPTION_RECORD_LENGTH + CONTEXT_FRAME_LENGTH
|
|
.ENDPROLOG
|
|
|
|
/* Clear direction flag */
|
|
cld
|
|
|
|
/* Dispatch the exception */
|
|
call RtlDispatchException
|
|
|
|
/* Check for success */
|
|
or al, al
|
|
jz RaiseException
|
|
|
|
/* We're fine, continue execution */
|
|
lea rcx, [rsp] /* ContextRecord */
|
|
mov dl, 0 /* TestAlert */
|
|
call ZwContinue
|
|
|
|
/* Exit */
|
|
jmp Exit
|
|
|
|
RaiseException:
|
|
|
|
/* Raise the exception */
|
|
lea rcx, [rsp + CONTEXT_FRAME_LENGTH] /* ExceptionRecord */
|
|
lea rdx, [rsp] /* ContextRecord */
|
|
xor r8, r8
|
|
call ZwRaiseException
|
|
|
|
Exit:
|
|
lea rcx, [rsp + CONTEXT_FRAME_LENGTH] /* ExceptionRecord */
|
|
mov rdx, rax
|
|
call KiUserExceptionDispatcherNested
|
|
ret
|
|
|
|
.ENDP
|
|
|
|
/*
|
|
VOID
|
|
KiUserExceptionDispatcherNested(
|
|
_In_ ExceptionRecord<rcx>,
|
|
_In_ Status<edx>
|
|
)
|
|
*/
|
|
.PROC KiUserExceptionDispatcherNested
|
|
/* Allocate space for the nested exception record */
|
|
sub rsp, EXCEPTION_RECORD_LENGTH
|
|
.ALLOCSTACK EXCEPTION_RECORD_LENGTH
|
|
.ENDPROLOG
|
|
|
|
/* Set it up */
|
|
mov dword ptr [rsp + ErNumberParameters], 0
|
|
mov dword ptr [rsp + ErExceptionFlags], EXCEPTION_NONCONTINUABLE
|
|
mov [rsp + ErExceptionRecord], rcx
|
|
mov [rsp + ErExceptionCode], edx
|
|
|
|
/* Raise the exception */
|
|
mov rcx, rsp
|
|
call RtlRaiseException
|
|
|
|
/* Cleanup stack and return */
|
|
add rsp, EXCEPTION_RECORD_LENGTH
|
|
ret
|
|
.ENDP
|
|
|
|
END
|
|
|