Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278/* * 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:PROCEXTERN LdrpInit:PROCEXTERN ZwCallbackReturn:PROCEXTERN RtlRaiseStatus:PROC.dataWow64PrepareForException: .quad 0.codePUBLIC LdrInitializeThunk.PROC LdrInitializeThunk mov rbp, 0 .setframe rbp, 0 .endprolog /* First parameter is the APC context */ mov rcx, r9 jmp LdrpInit.ENDPPUBLIC 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.ENDPPUBLIC KiRaiseUserExceptionDispatcher.PROC KiRaiseUserExceptionDispatcher .endprolog int 3.ENDPPUBLIC 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 /* Check the WOW64 callback */ mov rax, qword ptr Wow64PrepareForException[rip] test rax, rax jz .NoWow64 /* Prepare for WOW64 exception dispatching */ lea rcx, [rsp + CONTEXT_FRAME_LENGTH] /* ExceptionRecord */ lea rdx, [rsp] /* ContextRecord */ call rax.NoWow64: /* Dispatch the exception */ lea rcx, [rsp + CONTEXT_FRAME_LENGTH] /* ExceptionRecord */ lea rdx, [rsp] /* ContextRecord */ 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 ExitRaiseException: /* Raise the exception */ lea rcx, [rsp + CONTEXT_FRAME_LENGTH] /* ExceptionRecord */ lea rdx, [rsp] /* ContextRecord */ xor r8, r8 call ZwRaiseExceptionExit: 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.ENDPEND