mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:53:06 +00:00
[NTOS] Fix unwinding through KiThreadStartup
This commit is contained in:
parent
66aa25b1cd
commit
e923912f94
3 changed files with 67 additions and 24 deletions
|
@ -10,6 +10,7 @@
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ksamd64.inc>
|
#include <ksamd64.inc>
|
||||||
|
#include <trapamd64.inc>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BOOLEAN
|
* BOOLEAN
|
||||||
|
@ -70,10 +71,7 @@ PUBLIC KiThreadStartup
|
||||||
* mov [rsp + SfP3Home], r8
|
* mov [rsp + SfP3Home], r8
|
||||||
* mov [rsp + SfP4Home], r9
|
* mov [rsp + SfP4Home], r9
|
||||||
*/
|
*/
|
||||||
|
.allocstack (5 * 8)
|
||||||
/* Terminate the unwind chain, by setting rbp as frame pointer,
|
|
||||||
which contains 0 */
|
|
||||||
.setframe rbp, 0
|
|
||||||
.endprolog
|
.endprolog
|
||||||
|
|
||||||
/* Clear all the non-volatile registers, so the thread won't be tempted to
|
/* Clear all the non-volatile registers, so the thread won't be tempted to
|
||||||
|
@ -101,21 +99,50 @@ PUBLIC KiThreadStartup
|
||||||
mov r8, [rsp + SfP3Home] /* ? */
|
mov r8, [rsp + SfP3Home] /* ? */
|
||||||
call qword ptr [rsp + SfP4Home] /* SystemRoutine */
|
call qword ptr [rsp + SfP4Home] /* SystemRoutine */
|
||||||
|
|
||||||
/* The thread returned. If it was a user-thread, we have a return address
|
/* Return to the exit code */
|
||||||
and all is well, otherwise this is very bad. */
|
add rsp, 5 * 8
|
||||||
mov rcx, [rsp + SfReturn]
|
ret
|
||||||
or rcx, rcx
|
.ENDP
|
||||||
jnz .leave
|
|
||||||
|
|
||||||
/* A system thread returned...this is very bad! */
|
PUBLIC KiInvalidSystemThreadStartupExit
|
||||||
int 3
|
.PROC KiInvalidSystemThreadStartupExit
|
||||||
|
.endprolog
|
||||||
|
|
||||||
.leave:
|
/* This is invalid! */
|
||||||
/* It was a user thread, set our trapframe for the System Call Exit Dispatcher */
|
int HEX(2C)
|
||||||
lea rcx, [rsp + 6 * 8 + KEXCEPTION_FRAME_LENGTH]
|
nop
|
||||||
|
.ENDP
|
||||||
|
|
||||||
|
PUBLIC KiUserThreadStartupExit
|
||||||
|
.PROC KiUserThreadStartupExit
|
||||||
|
.allocstack (KEXCEPTION_FRAME_LENGTH - 8)
|
||||||
|
.savereg rbp, ExRbp
|
||||||
|
.savereg rbx, ExRbx
|
||||||
|
.savereg rdi, ExRdi
|
||||||
|
.savereg rsi, ExRsi
|
||||||
|
.savereg r12, ExR12
|
||||||
|
.savereg r13, ExR13
|
||||||
|
.savereg r14, ExR14
|
||||||
|
.savereg r15, ExR15
|
||||||
|
.savexmm128 xmm6, ExXmm6
|
||||||
|
.savexmm128 xmm7, ExXmm7
|
||||||
|
.savexmm128 xmm8, ExXmm8
|
||||||
|
.savexmm128 xmm9, ExXmm9
|
||||||
|
.savexmm128 xmm10, ExXmm10
|
||||||
|
.savexmm128 xmm11, ExXmm11
|
||||||
|
.savexmm128 xmm12, ExXmm12
|
||||||
|
.savexmm128 xmm13, ExXmm13
|
||||||
|
.savexmm128 xmm14, ExXmm14
|
||||||
|
.savexmm128 xmm15, ExXmm15
|
||||||
|
.endprolog
|
||||||
|
|
||||||
|
/* Restore the exception frame */
|
||||||
|
RESTORE_EXCEPTION_STATE
|
||||||
|
|
||||||
|
/* Point rcx to the trap frame */
|
||||||
|
lea rcx, [rsp + 8]
|
||||||
|
|
||||||
/* Return to the trap exit code */
|
/* Return to the trap exit code */
|
||||||
add rsp, 5 * 8
|
|
||||||
ret
|
ret
|
||||||
.ENDP
|
.ENDP
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
extern void KiInvalidSystemThreadStartupExit(void);
|
||||||
|
extern void KiUserThreadStartupExit(void);
|
||||||
|
extern void KiServiceExit3(void);
|
||||||
|
|
||||||
typedef struct _KUINIT_FRAME
|
typedef struct _KUINIT_FRAME
|
||||||
{
|
{
|
||||||
KSWITCH_FRAME CtxSwitchFrame;
|
KSWITCH_FRAME CtxSwitchFrame;
|
||||||
|
@ -98,8 +102,11 @@ KiInitializeContextThread(IN PKTHREAD Thread,
|
||||||
/* Terminate the Exception Handler List */
|
/* Terminate the Exception Handler List */
|
||||||
TrapFrame->ExceptionFrame = 0;
|
TrapFrame->ExceptionFrame = 0;
|
||||||
|
|
||||||
/* We return to ... */
|
/* KiThreadStartup returns to KiUserThreadStartupExit */
|
||||||
StartFrame->Return = (ULONG64)KiServiceExit2;
|
StartFrame->Return = (ULONG64)KiUserThreadStartupExit;
|
||||||
|
|
||||||
|
/* KiUserThreadStartupExit returns to KiServiceExit3 */
|
||||||
|
InitFrame->ExceptionFrame.Return = (ULONG64)KiServiceExit3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -121,8 +128,8 @@ KiInitializeContextThread(IN PKTHREAD Thread,
|
||||||
/* No NPX State */
|
/* No NPX State */
|
||||||
Thread->NpxState = 0xA;
|
Thread->NpxState = 0xA;
|
||||||
|
|
||||||
/* We have no return address! */
|
/* This must never return! */
|
||||||
StartFrame->Return = 0;
|
StartFrame->Return = (ULONG64)KiInvalidSystemThreadStartupExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the Context Switch Frame */
|
/* Set up the Context Switch Frame */
|
||||||
|
|
|
@ -930,16 +930,27 @@ PUBLIC KiServiceExit2
|
||||||
.PROC KiServiceExit2
|
.PROC KiServiceExit2
|
||||||
.ENDPROLOG
|
.ENDPROLOG
|
||||||
|
|
||||||
|
// FIXME: this should probably also restore an exception frame
|
||||||
|
|
||||||
|
mov rsp, rcx
|
||||||
|
.ENDP
|
||||||
|
|
||||||
|
PUBLIC KiServiceExit3
|
||||||
|
.PROC KiServiceExit3
|
||||||
|
.PUSHFRAME
|
||||||
|
.ALLOCSTACK (KTRAP_FRAME_LENGTH - MachineFrameLength)
|
||||||
|
.ENDPROLOG
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
/* Get the current IRQL and compare it to the trap frame */
|
/* Get the current IRQL and compare it to the trap frame */
|
||||||
mov rax, cr8
|
mov rax, cr8
|
||||||
cmp byte ptr [rcx + KTRAP_FRAME_PreviousIrql], al
|
cmp byte ptr [rsp + KTRAP_FRAME_PreviousIrql], al
|
||||||
je KiServiceExit2_ok1
|
je KiServiceExit2_ok1
|
||||||
int HEX(2C)
|
int HEX(2C)
|
||||||
|
|
||||||
KiServiceExit2_ok1:
|
KiServiceExit2_ok1:
|
||||||
/* Check if this is a user mode exit */
|
/* Check if this is a user mode exit */
|
||||||
mov ah, byte ptr [rcx + KTRAP_FRAME_SegCs]
|
mov ah, byte ptr [rsp + KTRAP_FRAME_SegCs]
|
||||||
test ah, 1
|
test ah, 1
|
||||||
jz KiServiceExit2_kernel
|
jz KiServiceExit2_kernel
|
||||||
|
|
||||||
|
@ -951,10 +962,8 @@ KiServiceExit2_ok1:
|
||||||
KiServiceExit2_kernel:
|
KiServiceExit2_kernel:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mov rbp, rcx
|
|
||||||
mov rsp, rcx
|
|
||||||
|
|
||||||
/* Return */
|
/* Return */
|
||||||
|
mov rbp, rsp
|
||||||
ExitTrap TF_SAVE_ALL
|
ExitTrap TF_SAVE_ALL
|
||||||
.ENDP
|
.ENDP
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue