mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 04:20:46 +00:00
[ASM/AMD64]
- Add multiple amd64 asm constant and structure offset definitions - Add more unwind information to the amd64 trap entry code - Add IRQL check, APC check and segment sanitize code to trap entry/exit svn path=/trunk/; revision=55404
This commit is contained in:
parent
0fcb7d138d
commit
de74279d5b
3 changed files with 133 additions and 57 deletions
|
@ -16,6 +16,16 @@
|
|||
#include <wdbgexts.h>
|
||||
#include <kddll.h>
|
||||
|
||||
#ifdef _M_AMD64
|
||||
enum
|
||||
{
|
||||
P1Home = 1 * sizeof(PVOID),
|
||||
P2Home = 2 * sizeof(PVOID),
|
||||
P3Home = 3 * sizeof(PVOID),
|
||||
P4Home = 4 * sizeof(PVOID),
|
||||
};
|
||||
#endif
|
||||
|
||||
// FIXME: where to put this?
|
||||
typedef struct _FIBER /* Field offsets: */
|
||||
{ /* 32 bit 64 bit */
|
||||
|
|
|
@ -112,10 +112,10 @@ CONSTANT(EXCEPTION_NPX_ERROR),
|
|||
CONSTANT(EXCEPTION_ALIGNMENT_CHECK),
|
||||
|
||||
HEADER("Argument Home Address"),
|
||||
OFFSET(P1Home, CONTEXT, P1Home),
|
||||
OFFSET(P2Home, CONTEXT, P1Home),
|
||||
OFFSET(P3Home, CONTEXT, P1Home),
|
||||
OFFSET(P4Home, CONTEXT, P1Home),
|
||||
CONSTANT(P1Home),
|
||||
CONSTANT(P2Home),
|
||||
CONSTANT(P3Home),
|
||||
CONSTANT(P4Home),
|
||||
|
||||
HEADER("CONTEXT"),
|
||||
OFFSET(CONTEXT_P1Home, CONTEXT, P1Home),
|
||||
|
@ -377,53 +377,55 @@ OFFSET(PcHalReserved, KPCR, HalReserved),
|
|||
//OFFSET(PcNumber, KPCR, Number),
|
||||
//OFFSET(PcInterruptRequest, KPCR, InterruptRequest),
|
||||
//OFFSET(PcIdleHalt, KPCR, IdleHalt),
|
||||
//OFFSET(PcCurrentThread, KPCR, CurrentThread),
|
||||
OFFSET(PcCurrentThread, KIPCR, Prcb.CurrentThread),
|
||||
//OFFSET(PcNextThread, KPCR, NextThread),
|
||||
//OFFSET(PcIdleThread, KPCR, IdleThread),
|
||||
//OFFSET(PcIpiFrozen, KPCR, IpiFrozen),
|
||||
//OFFSET(PcNestingLevel, KPCR, NestingLevel),
|
||||
//OFFSET(PcRspBase, KPCR, RspBase),
|
||||
OFFSET(PcRspBase, KIPCR, Prcb.RspBase),
|
||||
//OFFSET(PcPrcbLock, KPCR, PrcbLock),
|
||||
OFFSET(PcSetMember, KIPCR, Prcb.SetMember),
|
||||
#if 0
|
||||
OFFSET(PcSetMember, KPCR, SetMember),
|
||||
OFFSET(PcCr0, KPCR, Cr0),
|
||||
OFFSET(PcCr2, KPCR, Cr2),
|
||||
OFFSET(PcCr3, KPCR, Cr3),
|
||||
OFFSET(PcCr4, KPCR, Cr4),
|
||||
OFFSET(PcKernelDr0, KPCR, KernelDr0),
|
||||
OFFSET(PcKernelDr1, KPCR, KernelDr1),
|
||||
OFFSET(PcKernelDr2, KPCR, KernelDr2),
|
||||
OFFSET(PcKernelDr3, KPCR, KernelDr3),
|
||||
OFFSET(PcKernelDr7, KPCR, KernelDr7),
|
||||
OFFSET(PcGdtrLimit, KPCR, GdtrLimit),
|
||||
OFFSET(PcGdtrBase, KPCR, GdtrBase),
|
||||
OFFSET(PcIdtrLimit, KPCR, IdtrLimit),
|
||||
OFFSET(PcIdtrBase, KPCR, IdtrBase),
|
||||
OFFSET(PcTr, KPCR, Tr),
|
||||
OFFSET(PcLdtr, KPCR, Ldtr),
|
||||
OFFSET(PcDebugControl, KPCR, DebugControl),
|
||||
OFFSET(PcLastBranchToRip, KPCR, LastBranchToRip),
|
||||
OFFSET(PcLastBranchFromRip, KPCR, LastBranchFromRip),
|
||||
OFFSET(PcLastExceptionToRip, KPCR, LastExceptionToRip),
|
||||
OFFSET(PcLastExceptionFromRip, KPCR, LastExceptionFromRip),
|
||||
OFFSET(PcCr8, KPCR, Cr8),
|
||||
OFFSET(PcCpuType, KPCR, CpuType),
|
||||
OFFSET(PcCpuID, KPCR, CpuID),
|
||||
OFFSET(PcCpuStep, KPCR, CpuStep),
|
||||
OFFSET(PcCpuVendor, KPCR, CpuVendor),
|
||||
OFFSET(PcVirtualApicAssist, KPCR, VirtualApicAssist),
|
||||
OFFSET(PcCFlushSize, KPCR, CFlushSize),
|
||||
OFFSET(PcDeferredReadyListHead, KPCR, DeferredReadyListHead),
|
||||
OFFSET(PcSystemCalls, KPCR, SystemCalls),
|
||||
OFFSET(PcDpcRoutineActive, KPCR, DpcRoutineActive),
|
||||
OFFSET(PcInterruptCount, KPCR, InterruptCount),
|
||||
OFFSET(PcDebuggerSavedIRQL, KPCR, DebuggerSavedIRQL),
|
||||
OFFSET(PcTickOffset, KPCR, TickOffset),
|
||||
OFFSET(PcMasterOffset, KPCR, MasterOffset),
|
||||
OFFSET(PcSkipTick, KPCR, SkipTick),
|
||||
OFFSET(PcStartCycles, KPCR, StartCycles),
|
||||
SIZE(ProcessorControlRegisterLength, KPCR),
|
||||
OFFSET(PcCr0, KIPCR, Prcb.Cr0),
|
||||
OFFSET(PcCr2, KIPCR, Prcb.Cr2),
|
||||
OFFSET(PcCr3, KIPCR, Prcb.Cr3),
|
||||
OFFSET(PcCr4, KIPCR, Prcb.Cr4),
|
||||
OFFSET(PcKernelDr0, KIPCR, Prcb.KernelDr0),
|
||||
OFFSET(PcKernelDr1, KIPCR, Prcb.KernelDr1),
|
||||
OFFSET(PcKernelDr2, KIPCR, Prcb.KernelDr2),
|
||||
OFFSET(PcKernelDr3, KIPCR, Prcb.KernelDr3),
|
||||
OFFSET(PcKernelDr7, KIPCR, Prcb.KernelDr7),
|
||||
OFFSET(PcGdtrLimit, KIPCR, Prcb.GdtrLimit),
|
||||
OFFSET(PcGdtrBase, KIPCR, Prcb.GdtrBase),
|
||||
OFFSET(PcIdtrLimit, KIPCR, IdtrLimit),
|
||||
OFFSET(PcIdtrBase, KIPCR, IdtrBase),
|
||||
OFFSET(PcTr, KIPCR, Tr),
|
||||
OFFSET(PcLdtr, KIPCR, Ldtr),
|
||||
OFFSET(PcDebugControl, KIPCR, DebugControl),
|
||||
OFFSET(PcLastBranchToRip, KIPCR, LastBranchToRip),
|
||||
OFFSET(PcLastBranchFromRip, KIPCR, LastBranchFromRip),
|
||||
OFFSET(PcLastExceptionToRip, KIPCR, LastExceptionToRip),
|
||||
OFFSET(PcLastExceptionFromRip, KIPCR, LastExceptionFromRip),
|
||||
OFFSET(PcCr8, KIPCR, Cr8),
|
||||
#endif
|
||||
OFFSET(PcCpuType, KIPCR, Prcb.CpuType),
|
||||
OFFSET(PcCpuID, KIPCR, Prcb.CpuID),
|
||||
OFFSET(PcCpuStep, KIPCR, Prcb.CpuStep),
|
||||
OFFSET(PcCpuVendor, KIPCR, Prcb.CpuVendor),
|
||||
OFFSET(PcCFlushSize, KIPCR, Prcb.CFlushSize),
|
||||
OFFSET(PcDeferredReadyListHead, KIPCR, Prcb.DeferredReadyListHead),
|
||||
OFFSET(PcSystemCalls, KIPCR, Prcb.KeSystemCalls),
|
||||
OFFSET(PcDpcRoutineActive, KIPCR, Prcb.DpcRoutineActive),
|
||||
OFFSET(PcInterruptCount, KIPCR, Prcb.InterruptCount),
|
||||
OFFSET(PcDebuggerSavedIRQL, KIPCR, Prcb.DebuggerSavedIRQL),
|
||||
OFFSET(PcTickOffset, KIPCR, Prcb.TickOffset),
|
||||
OFFSET(PcMasterOffset, KIPCR, Prcb.MasterOffset),
|
||||
OFFSET(PcSkipTick, KIPCR, Prcb.SkipTick),
|
||||
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
|
||||
OFFSET(PcVirtualApicAssist, KIPCR, Prcb.VirtualApicAssist),
|
||||
OFFSET(PcStartCycles, KIPCR, Prcb.StartCycles),
|
||||
#endif
|
||||
SIZE(ProcessorControlRegisterLength, KIPCR),
|
||||
|
||||
HEADER("KPROCESSOR_STATE"),
|
||||
OFFSET(PsSpecialRegisters, KPROCESSOR_STATE, SpecialRegisters),
|
||||
|
@ -578,4 +580,33 @@ OFFSET(EXCEPTION_RECORD_ExceptionAddress, EXCEPTION_RECORD, ExceptionAddress),
|
|||
OFFSET(EXCEPTION_RECORD_NumberParameters, EXCEPTION_RECORD, NumberParameters),
|
||||
OFFSET(EXCEPTION_RECORD_ExceptionInformation, EXCEPTION_RECORD, ExceptionInformation),
|
||||
|
||||
HEADER("KTHREAD"),
|
||||
OFFSET(KTHREAD_WAIT_IRQL, KTHREAD, WaitIrql),
|
||||
OFFSET(KTHREAD_TrapFrame, KTHREAD, TrapFrame),
|
||||
OFFSET(KTHREAD_PreviousMode, KTHREAD, PreviousMode),
|
||||
OFFSET(KTHREAD_KernelStack, KTHREAD, KernelStack),
|
||||
OFFSET(KTHREAD_UserApcPending, KTHREAD, ApcState.UserApcPending),
|
||||
|
||||
HEADER("KINTERRUPT"),
|
||||
|
||||
OFFSET(KINTERRUPT_Type, KINTERRUPT, Type),
|
||||
OFFSET(KINTERRUPT_Size, KINTERRUPT, Size),
|
||||
OFFSET(KINTERRUPT_InterruptListEntry, KINTERRUPT, InterruptListEntry),
|
||||
OFFSET(KINTERRUPT_ServiceRoutine, KINTERRUPT, ServiceRoutine),
|
||||
OFFSET(KINTERRUPT_ServiceContext, KINTERRUPT, ServiceContext),
|
||||
OFFSET(KINTERRUPT_SpinLock, KINTERRUPT, SpinLock),
|
||||
OFFSET(KINTERRUPT_TickCount, KINTERRUPT, TickCount),
|
||||
OFFSET(KINTERRUPT_ActualLock, KINTERRUPT, ActualLock),
|
||||
OFFSET(KINTERRUPT_DispatchAddress, KINTERRUPT, DispatchAddress),
|
||||
OFFSET(KINTERRUPT_Vector, KINTERRUPT, Vector),
|
||||
OFFSET(KINTERRUPT_Irql, KINTERRUPT, Irql),
|
||||
OFFSET(KINTERRUPT_SynchronizeIrql, KINTERRUPT, SynchronizeIrql),
|
||||
OFFSET(KINTERRUPT_FloatingSave, KINTERRUPT, FloatingSave),
|
||||
OFFSET(KINTERRUPT_Connected, KINTERRUPT, Connected),
|
||||
OFFSET(KINTERRUPT_Number, KINTERRUPT, Number),
|
||||
OFFSET(KINTERRUPT_ShareVector, KINTERRUPT, ShareVector),
|
||||
OFFSET(KINTERRUPT_Mode, KINTERRUPT, Mode),
|
||||
OFFSET(KINTERRUPT_ServiceCount, KINTERRUPT, ServiceCount),
|
||||
OFFSET(KINTERRUPT_DispatchCount, KINTERRUPT, DispatchCount),
|
||||
OFFSET(KINTERRUPT_TrapFrame, KINTERRUPT, TrapFrame),
|
||||
OFFSET(KINTERRUPT_DispatchCode, KINTERRUPT, DispatchCode),
|
||||
|
|
|
@ -11,6 +11,7 @@ TF_SAVE_ALL = (TF_VOLATILES OR TF_NONVOLATILES OR TF_XMM OR TF_SEGME
|
|||
TF_HAS_ERROR_CODE = HEX(40)
|
||||
TF_SEND_EOI = HEX(80)
|
||||
//TF_SYSTEMSERVICE = (TRAPFLAG_VOLATILES or TRAPFLAG_DEBUG)
|
||||
TF_CHECKUSERAPC = HEX(100)
|
||||
|
||||
/*
|
||||
* Stack Layout:
|
||||
|
@ -28,7 +29,7 @@ TF_SEND_EOI = HEX(80)
|
|||
* EnterTrap - Allocate KTRAP_FRAME_LENGTH and save registers to it
|
||||
*/
|
||||
MACRO(EnterTrap, Flags)
|
||||
LOCAL dont_swap
|
||||
LOCAL kernel_mode_entry
|
||||
|
||||
/* Save the trap flags for this trap */
|
||||
CurrentTrapFlags = VAL(Flags)
|
||||
|
@ -45,22 +46,29 @@ MACRO(EnterTrap, Flags)
|
|||
/* Make room for a KTRAP_FRAME */
|
||||
sub rsp, (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME)
|
||||
.allocstack (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME)
|
||||
.endprolog
|
||||
|
||||
/* Save rbp and rax */
|
||||
mov [rsp + KTRAP_FRAME_Rbp], rbp
|
||||
.savereg rbp, KTRAP_FRAME_Rbp
|
||||
mov [rsp + KTRAP_FRAME_Rax], rax
|
||||
.savereg rax, KTRAP_FRAME_Rax
|
||||
|
||||
/* Point rbp to the KTRAP_FRAME */
|
||||
lea rbp, [rsp]
|
||||
.setframe rbp, 0
|
||||
|
||||
if (Flags AND TF_NONVOLATILES)
|
||||
/* Save non-volatile registers */
|
||||
mov [rbp + KTRAP_FRAME_Rbx], rbx
|
||||
.savereg rbx, KTRAP_FRAME_Rbx
|
||||
mov [rbp + KTRAP_FRAME_Rdi], rdi
|
||||
.savereg rdi, KTRAP_FRAME_Rdi
|
||||
mov [rbp + KTRAP_FRAME_Rsi], rsi
|
||||
.savereg rsi, KTRAP_FRAME_Rsi
|
||||
endif
|
||||
|
||||
.endprolog
|
||||
|
||||
if (Flags AND TF_VOLATILES)
|
||||
/* Save volatile registers */
|
||||
mov [rbp + KTRAP_FRAME_Rcx], rcx
|
||||
|
@ -89,19 +97,25 @@ MACRO(EnterTrap, Flags)
|
|||
mov [rbp + KTRAP_FRAME_SegGs], gs
|
||||
endif
|
||||
|
||||
/* Save previous mode and swap gs when it was UserMode */
|
||||
/* Save previous mode and check if it was user mode */
|
||||
mov ax, [rbp + KTRAP_FRAME_SegCs]
|
||||
and al, 1
|
||||
mov [rbp + KTRAP_FRAME_PreviousMode], al
|
||||
jz dont_swap
|
||||
swapgs
|
||||
dont_swap:
|
||||
jz kernel_mode_entry
|
||||
|
||||
if (Flags AND TF_IRQL)
|
||||
/* Set sane segments */
|
||||
mov ax, (KGDT64_R3_DATA or RPL_MASK)
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
swapgs
|
||||
|
||||
kernel_mode_entry:
|
||||
|
||||
// if (Flags AND TF_IRQL)
|
||||
/* Save previous irql */
|
||||
mov rax, cr8
|
||||
mov [rbp + KTRAP_FRAME_PreviousIrql], al
|
||||
endif
|
||||
// endif
|
||||
|
||||
if (Flags AND TF_DEBUG)
|
||||
/* Save debug registers */
|
||||
|
@ -127,7 +141,16 @@ ENDM
|
|||
* ExitTrap - Restore registers and free stack space
|
||||
*/
|
||||
MACRO(ExitTrap, Flags)
|
||||
LOCAL dont_swap_back
|
||||
LOCAL kernel_mode_return
|
||||
|
||||
#if DBG
|
||||
/* Check previous irql */
|
||||
mov rax, cr8
|
||||
cmp [rbp + KTRAP_FRAME_PreviousIrql], al
|
||||
je .irql_ok
|
||||
int 3
|
||||
.irql_ok:
|
||||
#endif
|
||||
|
||||
if (Flags AND TF_SEGMENTS)
|
||||
/* Restore segment selectors */
|
||||
|
@ -142,10 +165,22 @@ MACRO(ExitTrap, Flags)
|
|||
mov cr8, rax
|
||||
endif
|
||||
|
||||
test byte ptr [rbp + KTRAP_FRAME_PreviousMode], 1
|
||||
jz dont_swap_back
|
||||
/* Check if we came from user mode */
|
||||
test byte ptr [rbp + KTRAP_FRAME_SegCs], 1
|
||||
jz kernel_mode_return
|
||||
|
||||
if (Flags AND TF_CHECKUSERAPC)
|
||||
/* Load current thread into r10 */
|
||||
mov r10, gs:[PcCurrentThread]
|
||||
cmp byte ptr [r10 + KTHREAD_UserApcPending], 0
|
||||
jne KiExitToUserApc
|
||||
|
||||
endif
|
||||
|
||||
/* Swap gs to user mode */
|
||||
swapgs
|
||||
dont_swap_back:
|
||||
|
||||
kernel_mode_return:
|
||||
|
||||
if (Flags AND TF_NONVOLATILES)
|
||||
/* Restore non-volatile registers */
|
||||
|
@ -204,6 +239,6 @@ MACRO(TRAP_ENTRY, Trap, Flags)
|
|||
|
||||
/* Leave */
|
||||
ExitTrap Flags
|
||||
ENDFUNC &Trap
|
||||
ENDFUNC
|
||||
ENDM
|
||||
|
||||
|
|
Loading…
Reference in a new issue