mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
[FORMATTING] Fix the indentation mess in KDBG and use a consistent 4 spaces indentation.
svn path=/trunk/; revision=43014
This commit is contained in:
parent
5221d11896
commit
3e4016ea24
|
@ -69,10 +69,12 @@ KdPortPutByteEx(
|
||||||
#if defined(KDBG) || DBG
|
#if defined(KDBG) || DBG
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule);
|
KdbSymLoadUserModuleSymbols(
|
||||||
|
IN PLDR_DATA_TABLE_ENTRY LdrModule);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbSymFreeProcessSymbols(IN PEPROCESS Process);
|
KdbSymFreeProcessSymbols(
|
||||||
|
IN PEPROCESS Process);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbSymLoadDriverSymbols(
|
KdbSymLoadDriverSymbols(
|
||||||
|
@ -81,21 +83,27 @@ KdbSymLoadDriverSymbols(
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject);
|
KdbSymUnloadDriverSymbols(
|
||||||
|
IN PLDR_DATA_TABLE_ENTRY ModuleObject);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName,
|
KdbSymProcessBootSymbols(
|
||||||
|
IN PANSI_STRING AnsiFileName,
|
||||||
IN BOOLEAN FullName,
|
IN BOOLEAN FullName,
|
||||||
IN BOOLEAN LoadFromFile);
|
IN BOOLEAN LoadFromFile);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbSymProcessSymbols(IN PANSI_STRING FileName, IN PKD_SYMBOLS_INFO SymbolInfo);
|
KdbSymProcessSymbols(
|
||||||
|
IN PANSI_STRING FileName,
|
||||||
|
IN PKD_SYMBOLS_INFO SymbolInfo);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbSymPrintAddress(IN PVOID Address);
|
KdbSymPrintAddress(
|
||||||
|
IN PVOID Address);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbDeleteProcessHook(IN PEPROCESS Process);
|
KdbDeleteProcessHook(
|
||||||
|
IN PEPROCESS Process);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
KdbSymGetAddressInformation(
|
KdbSymGetAddressInformation(
|
||||||
|
@ -112,7 +120,8 @@ typedef struct _KDB_MODULE_INFO
|
||||||
ULONG_PTR Base;
|
ULONG_PTR Base;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
PROSSYM_INFO RosSymInfo;
|
PROSSYM_INFO RosSymInfo;
|
||||||
} KDB_MODULE_INFO, *PKDB_MODULE_INFO;
|
}
|
||||||
|
KDB_MODULE_INFO, *PKDB_MODULE_INFO;
|
||||||
|
|
||||||
/* MACROS FOR NON-KDBG BUILDS ************************************************/
|
/* MACROS FOR NON-KDBG BUILDS ************************************************/
|
||||||
|
|
||||||
|
@ -153,7 +162,8 @@ typedef enum _KD_CONTINUE_TYPE
|
||||||
kdContinue = 0,
|
kdContinue = 0,
|
||||||
kdDoNotHandleException,
|
kdDoNotHandleException,
|
||||||
kdHandleException
|
kdHandleException
|
||||||
} KD_CONTINUE_TYPE;
|
}
|
||||||
|
KD_CONTINUE_TYPE;
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
VOID
|
VOID
|
||||||
|
@ -327,7 +337,8 @@ typedef struct _KDP_DEBUG_MODE
|
||||||
/* Generic Value */
|
/* Generic Value */
|
||||||
ULONG Value;
|
ULONG Value;
|
||||||
};
|
};
|
||||||
} KDP_DEBUG_MODE;
|
}
|
||||||
|
KDP_DEBUG_MODE;
|
||||||
|
|
||||||
/* KD Internal Debug Services */
|
/* KD Internal Debug Services */
|
||||||
typedef enum _KDP_DEBUG_SERVICE
|
typedef enum _KDP_DEBUG_SERVICE
|
||||||
|
@ -344,7 +355,8 @@ typedef enum _KDP_DEBUG_SERVICE
|
||||||
KdSpare3 = 0x24, /* j */
|
KdSpare3 = 0x24, /* j */
|
||||||
EnterDebugger = 0x25, /* k */
|
EnterDebugger = 0x25, /* k */
|
||||||
ThatsWhatSheSaid = 69 /* FIGURE IT OUT */
|
ThatsWhatSheSaid = 69 /* FIGURE IT OUT */
|
||||||
} KDP_DEBUG_SERVICE;
|
}
|
||||||
|
KDP_DEBUG_SERVICE;
|
||||||
|
|
||||||
/* Dispatch Table for Wrapper Functions */
|
/* Dispatch Table for Wrapper Functions */
|
||||||
typedef struct _KD_DISPATCH_TABLE
|
typedef struct _KD_DISPATCH_TABLE
|
||||||
|
@ -354,7 +366,8 @@ typedef struct _KD_DISPATCH_TABLE
|
||||||
PKDP_PRINT_ROUTINE KdpPrintRoutine;
|
PKDP_PRINT_ROUTINE KdpPrintRoutine;
|
||||||
PKDP_PROMPT_ROUTINE KdpPromptRoutine;
|
PKDP_PROMPT_ROUTINE KdpPromptRoutine;
|
||||||
PKDP_EXCEPTION_ROUTINE KdpExceptionRoutine;
|
PKDP_EXCEPTION_ROUTINE KdpExceptionRoutine;
|
||||||
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
}
|
||||||
|
KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
||||||
|
|
||||||
/* The current Debugging Mode */
|
/* The current Debugging Mode */
|
||||||
extern KDP_DEBUG_MODE KdpDebugMode;
|
extern KDP_DEBUG_MODE KdpDebugMode;
|
||||||
|
|
|
@ -31,6 +31,7 @@ _KdbEnter:
|
||||||
pushl %gs /* Gs */
|
pushl %gs /* Gs */
|
||||||
movl %dr7, %eax
|
movl %dr7, %eax
|
||||||
pushl %eax /* Dr7 */
|
pushl %eax /* Dr7 */
|
||||||
|
|
||||||
/* Clear all breakpoint enables in dr7. */
|
/* Clear all breakpoint enables in dr7. */
|
||||||
andl $0xFFFF0000, %eax
|
andl $0xFFFF0000, %eax
|
||||||
movl %eax, %dr7
|
movl %eax, %dr7
|
||||||
|
|
|
@ -107,34 +107,38 @@ static const CHAR *ExceptionNrToString[] =
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame);
|
KiSsFromTrapFrame(
|
||||||
|
IN PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame);
|
KiEspFromTrapFrame(
|
||||||
|
IN PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
|
KiSsToTrapFrame(
|
||||||
|
IN PKTRAP_FRAME TrapFrame,
|
||||||
IN ULONG Ss);
|
IN ULONG Ss);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
|
KiEspToTrapFrame(
|
||||||
|
IN PKTRAP_FRAME TrapFrame,
|
||||||
IN ULONG Esp);
|
IN ULONG Esp);
|
||||||
|
|
||||||
/* ROS Internal. Please deprecate */
|
/* ROS Internal. Please deprecate */
|
||||||
NTHALAPI
|
NTHALAPI
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
HalReleaseDisplayOwnership(
|
HalReleaseDisplayOwnership();
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
KdbpTrapFrameToKdbTrapFrame(PKTRAP_FRAME TrapFrame, PKDB_KTRAP_FRAME KdbTrapFrame)
|
KdbpTrapFrameToKdbTrapFrame(
|
||||||
|
PKTRAP_FRAME TrapFrame,
|
||||||
|
PKDB_KTRAP_FRAME KdbTrapFrame)
|
||||||
{
|
{
|
||||||
ULONG TrapCr0, TrapCr2, TrapCr3, TrapCr4;
|
ULONG TrapCr0, TrapCr2, TrapCr3, TrapCr4;
|
||||||
|
|
||||||
|
@ -181,7 +185,9 @@ KdbpTrapFrameToKdbTrapFrame(PKTRAP_FRAME TrapFrame, PKDB_KTRAP_FRAME KdbTrapFram
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
KdbpKdbTrapFrameToTrapFrame(PKDB_KTRAP_FRAME KdbTrapFrame, PKTRAP_FRAME TrapFrame)
|
KdbpKdbTrapFrameToTrapFrame(
|
||||||
|
PKDB_KTRAP_FRAME KdbTrapFrame,
|
||||||
|
PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
/* Copy the TrapFrame only up to Eflags and zero the rest*/
|
/* Copy the TrapFrame only up to Eflags and zero the rest*/
|
||||||
RtlCopyMemory(TrapFrame, &KdbTrapFrame->Tf, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
|
RtlCopyMemory(TrapFrame, &KdbTrapFrame->Tf, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
|
||||||
|
@ -195,7 +201,8 @@ KdbpKdbTrapFrameToTrapFrame(PKDB_KTRAP_FRAME KdbTrapFrame, PKTRAP_FRAME TrapFram
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack,
|
KdbpKdbTrapFrameFromKernelStack(
|
||||||
|
PVOID KernelStack,
|
||||||
PKDB_KTRAP_FRAME KdbTrapFrame)
|
PKDB_KTRAP_FRAME KdbTrapFrame)
|
||||||
{
|
{
|
||||||
ULONG_PTR *StackPtr;
|
ULONG_PTR *StackPtr;
|
||||||
|
@ -262,7 +269,7 @@ KdbpOverwriteInstruction(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the old instruction back to the caller. */
|
/* Copy the old instruction back to the caller. */
|
||||||
if (OldInst != NULL)
|
if (OldInst)
|
||||||
{
|
{
|
||||||
Status = KdbpSafeReadMemory(OldInst, (PUCHAR)Address, 1);
|
Status = KdbpSafeReadMemory(OldInst, (PUCHAR)Address, 1);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -271,11 +278,13 @@ KdbpOverwriteInstruction(
|
||||||
{
|
{
|
||||||
MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
|
MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detach from process */
|
/* Detach from process */
|
||||||
if (CurrentProcess != Process)
|
if (CurrentProcess != Process)
|
||||||
{
|
{
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +314,8 @@ KdbpOverwriteInstruction(
|
||||||
* \retval FALSE Instruction is not a call.
|
* \retval FALSE Instruction is not a call.
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbpShouldStepOverInstruction(ULONG_PTR Eip)
|
KdbpShouldStepOverInstruction(
|
||||||
|
ULONG_PTR Eip)
|
||||||
{
|
{
|
||||||
UCHAR Mem[3];
|
UCHAR Mem[3];
|
||||||
ULONG i = 0;
|
ULONG i = 0;
|
||||||
|
@ -319,13 +329,16 @@ KdbpShouldStepOverInstruction(ULONG_PTR Eip)
|
||||||
/* Check if the current instruction is a call. */
|
/* Check if the current instruction is a call. */
|
||||||
while ((i < sizeof (Mem)) && (Mem[i] == 0x66 || Mem[i] == 0x67))
|
while ((i < sizeof (Mem)) && (Mem[i] == 0x66 || Mem[i] == 0x67))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (i == sizeof (Mem))
|
if (i == sizeof (Mem))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (Mem[i] == 0xE8 || Mem[i] == 0x9A || Mem[i] == 0xF2 || Mem[i] == 0xF3 ||
|
if (Mem[i] == 0xE8 || Mem[i] == 0x9A || Mem[i] == 0xF2 || Mem[i] == 0xF3 ||
|
||||||
(((i + 1) < sizeof (Mem)) && Mem[i] == 0xFF && (Mem[i+1] & 0x38) == 0x10))
|
(((i + 1) < sizeof (Mem)) && Mem[i] == 0xFF && (Mem[i+1] & 0x38) == 0x10))
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +352,8 @@ KdbpShouldStepOverInstruction(ULONG_PTR Eip)
|
||||||
* \retval FALSE No breakpoint was set.
|
* \retval FALSE No breakpoint was set.
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbpStepOverInstruction(ULONG_PTR Eip)
|
KdbpStepOverInstruction(
|
||||||
|
ULONG_PTR Eip)
|
||||||
{
|
{
|
||||||
LONG InstLen;
|
LONG InstLen;
|
||||||
|
|
||||||
|
@ -366,7 +380,8 @@ KdbpStepOverInstruction(ULONG_PTR Eip)
|
||||||
* \retval FALSE No breakpoint was set.
|
* \retval FALSE No breakpoint was set.
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbpStepIntoInstruction(ULONG_PTR Eip)
|
KdbpStepIntoInstruction(
|
||||||
|
ULONG_PTR Eip)
|
||||||
{
|
{
|
||||||
KDESCRIPTOR Idtr = {0};
|
KDESCRIPTOR Idtr = {0};
|
||||||
UCHAR Mem[2];
|
UCHAR Mem[2];
|
||||||
|
@ -455,6 +470,7 @@ KdbpGetNextBreakPointNr(
|
||||||
if (KdbBreakPoints[Start].Type != KdbBreakPointNone)
|
if (KdbBreakPoints[Start].Type != KdbBreakPointNone)
|
||||||
return Start;
|
return Start;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,26 +510,34 @@ KdbpGetBreakPointInfo(
|
||||||
}
|
}
|
||||||
|
|
||||||
bp = KdbBreakPoints + BreakPointNr;
|
bp = KdbBreakPoints + BreakPointNr;
|
||||||
if (Address != NULL)
|
if (Address)
|
||||||
*Address = bp->Address;
|
*Address = bp->Address;
|
||||||
if (Type != NULL)
|
|
||||||
|
if (Type)
|
||||||
*Type = bp->Type;
|
*Type = bp->Type;
|
||||||
|
|
||||||
if (bp->Type == KdbBreakPointHardware)
|
if (bp->Type == KdbBreakPointHardware)
|
||||||
{
|
{
|
||||||
if (Size != NULL)
|
if (Size)
|
||||||
*Size = bp->Data.Hw.Size;
|
*Size = bp->Data.Hw.Size;
|
||||||
if (AccessType != NULL)
|
|
||||||
|
if (AccessType)
|
||||||
*AccessType = bp->Data.Hw.AccessType;
|
*AccessType = bp->Data.Hw.AccessType;
|
||||||
if (DebugReg != NULL && bp->Enabled)
|
|
||||||
|
if (DebugReg && bp->Enabled)
|
||||||
*DebugReg = bp->Data.Hw.DebugReg;
|
*DebugReg = bp->Data.Hw.DebugReg;
|
||||||
}
|
}
|
||||||
if (Enabled != NULL)
|
|
||||||
|
if (Enabled)
|
||||||
*Enabled = bp->Enabled;
|
*Enabled = bp->Enabled;
|
||||||
if (Global != NULL)
|
|
||||||
|
if (Global)
|
||||||
*Global = bp->Global;
|
*Global = bp->Global;
|
||||||
if (Process != NULL)
|
|
||||||
|
if (Process)
|
||||||
*Process = bp->Process;
|
*Process = bp->Process;
|
||||||
if (ConditionExpression != NULL)
|
|
||||||
|
if (ConditionExpression)
|
||||||
*ConditionExpression = bp->ConditionExpression;
|
*ConditionExpression = bp->ConditionExpression;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -558,6 +582,7 @@ KdbpInsertBreakPoint(
|
||||||
KdbpPrint("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
|
KdbpPrint("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AccessType == KdbAccessExec && Size != 1)
|
if (AccessType == KdbAccessExec && Size != 1)
|
||||||
{
|
{
|
||||||
KdbpPrint("Size must be 1 for execution breakpoints.\n");
|
KdbpPrint("Size must be 1 for execution breakpoints.\n");
|
||||||
|
@ -571,22 +596,22 @@ KdbpInsertBreakPoint(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse conditon expression string and duplicate it */
|
/* Parse conditon expression string and duplicate it */
|
||||||
if (ConditionExpression != NULL)
|
if (ConditionExpression)
|
||||||
{
|
{
|
||||||
Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
|
Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
|
||||||
if (Condition == NULL)
|
if (!Condition)
|
||||||
{
|
{
|
||||||
if (ErrOffset >= 0)
|
if (ErrOffset >= 0)
|
||||||
KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
|
KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
|
||||||
else
|
else
|
||||||
KdbpPrint("Couldn't parse expression: %s", ErrMsg);
|
KdbpPrint("Couldn't parse expression: %s", ErrMsg);
|
||||||
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = strlen(ConditionExpression) + 1;
|
i = strlen(ConditionExpression) + 1;
|
||||||
ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG);
|
ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG);
|
||||||
RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i);
|
RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -611,10 +636,11 @@ KdbpInsertBreakPoint(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(i < (LONG)RTL_NUMBER_OF(KdbBreakPoints));
|
ASSERT(i < (LONG)RTL_NUMBER_OF(KdbBreakPoints));
|
||||||
|
|
||||||
/* Set the breakpoint */
|
/* Set the breakpoint */
|
||||||
ASSERT(KdbCurrentProcess != NULL);
|
ASSERT(KdbCurrentProcess);
|
||||||
KdbBreakPoints[i].Type = Type;
|
KdbBreakPoints[i].Type = Type;
|
||||||
KdbBreakPoints[i].Address = Address;
|
KdbBreakPoints[i].Address = Address;
|
||||||
KdbBreakPoints[i].Enabled = FALSE;
|
KdbBreakPoints[i].Enabled = FALSE;
|
||||||
|
@ -622,12 +648,13 @@ KdbpInsertBreakPoint(
|
||||||
KdbBreakPoints[i].Process = KdbCurrentProcess;
|
KdbBreakPoints[i].Process = KdbCurrentProcess;
|
||||||
KdbBreakPoints[i].ConditionExpression = ConditionExpressionDup;
|
KdbBreakPoints[i].ConditionExpression = ConditionExpressionDup;
|
||||||
KdbBreakPoints[i].Condition = Condition;
|
KdbBreakPoints[i].Condition = Condition;
|
||||||
|
|
||||||
if (Type == KdbBreakPointHardware)
|
if (Type == KdbBreakPointHardware)
|
||||||
{
|
{
|
||||||
|
|
||||||
KdbBreakPoints[i].Data.Hw.Size = Size;
|
KdbBreakPoints[i].Data.Hw.Size = Size;
|
||||||
KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
|
KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbBreakPointCount++;
|
KdbBreakPointCount++;
|
||||||
|
|
||||||
if (Type != KdbBreakPointTemporary)
|
if (Type != KdbBreakPointTemporary)
|
||||||
|
@ -637,7 +664,7 @@ KdbpInsertBreakPoint(
|
||||||
KdbpEnableBreakPoint(i, NULL);
|
KdbpEnableBreakPoint(i, NULL);
|
||||||
|
|
||||||
/* Return the breakpoint number */
|
/* Return the breakpoint number */
|
||||||
if (BreakPointNr != NULL)
|
if (BreakPointNr)
|
||||||
*BreakPointNr = i;
|
*BreakPointNr = i;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -658,30 +685,33 @@ KdbpDeleteBreakPoint(
|
||||||
{
|
{
|
||||||
if (BreakPointNr < 0)
|
if (BreakPointNr < 0)
|
||||||
{
|
{
|
||||||
ASSERT(BreakPoint != NULL);
|
ASSERT(BreakPoint);
|
||||||
BreakPointNr = BreakPoint - KdbBreakPoints;
|
BreakPointNr = BreakPoint - KdbBreakPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
|
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
|
||||||
{
|
{
|
||||||
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (BreakPoint == NULL)
|
|
||||||
|
if (!BreakPoint)
|
||||||
{
|
{
|
||||||
BreakPoint = KdbBreakPoints + BreakPointNr;
|
BreakPoint = KdbBreakPoints + BreakPointNr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPoint->Type == KdbBreakPointNone)
|
if (BreakPoint->Type == KdbBreakPointNone)
|
||||||
{
|
{
|
||||||
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPoint->Enabled &&
|
if (BreakPoint->Enabled && !KdbpDisableBreakPoint(-1, BreakPoint))
|
||||||
!KdbpDisableBreakPoint(-1, BreakPoint))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (BreakPoint->Type != KdbBreakPointTemporary)
|
if (BreakPoint->Type != KdbBreakPointTemporary)
|
||||||
KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
|
KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
|
||||||
|
|
||||||
BreakPoint->Type = KdbBreakPointNone;
|
BreakPoint->Type = KdbBreakPointNone;
|
||||||
KdbBreakPointCount--;
|
KdbBreakPointCount--;
|
||||||
|
|
||||||
|
@ -714,6 +744,7 @@ KdbpIsBreakPointOurs(
|
||||||
ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
|
ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
|
||||||
KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
|
KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
|
||||||
ASSERT(KdbSwBreakPoints[i]->Enabled);
|
ASSERT(KdbSwBreakPoints[i]->Enabled);
|
||||||
|
|
||||||
if (KdbSwBreakPoints[i]->Address == BpEip)
|
if (KdbSwBreakPoints[i]->Address == BpEip)
|
||||||
{
|
{
|
||||||
return KdbSwBreakPoints[i] - KdbBreakPoints;
|
return KdbSwBreakPoints[i] - KdbBreakPoints;
|
||||||
|
@ -723,11 +754,13 @@ KdbpIsBreakPointOurs(
|
||||||
else if (ExceptionCode == STATUS_SINGLE_STEP) /* Hardware interrupt */
|
else if (ExceptionCode == STATUS_SINGLE_STEP) /* Hardware interrupt */
|
||||||
{
|
{
|
||||||
UCHAR DebugReg;
|
UCHAR DebugReg;
|
||||||
|
|
||||||
for (i = 0; i < KdbHwBreakPointCount; i++)
|
for (i = 0; i < KdbHwBreakPointCount; i++)
|
||||||
{
|
{
|
||||||
ASSERT(KdbHwBreakPoints[i]->Type == KdbBreakPointHardware &&
|
ASSERT(KdbHwBreakPoints[i]->Type == KdbBreakPointHardware &&
|
||||||
KdbHwBreakPoints[i]->Enabled);
|
KdbHwBreakPoints[i]->Enabled);
|
||||||
DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
|
DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
|
||||||
|
|
||||||
if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
|
if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
|
||||||
{
|
{
|
||||||
return KdbHwBreakPoints[i] - KdbBreakPoints;
|
return KdbHwBreakPoints[i] - KdbBreakPoints;
|
||||||
|
@ -759,25 +792,28 @@ KdbpEnableBreakPoint(
|
||||||
|
|
||||||
if (BreakPointNr < 0)
|
if (BreakPointNr < 0)
|
||||||
{
|
{
|
||||||
ASSERT(BreakPoint != NULL);
|
ASSERT(BreakPoint);
|
||||||
BreakPointNr = BreakPoint - KdbBreakPoints;
|
BreakPointNr = BreakPoint - KdbBreakPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
|
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
|
||||||
{
|
{
|
||||||
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (BreakPoint == NULL)
|
|
||||||
|
if (!BreakPoint)
|
||||||
{
|
{
|
||||||
BreakPoint = KdbBreakPoints + BreakPointNr;
|
BreakPoint = KdbBreakPoints + BreakPointNr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPoint->Type == KdbBreakPointNone)
|
if (BreakPoint->Type == KdbBreakPointNone)
|
||||||
{
|
{
|
||||||
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPoint->Enabled == TRUE)
|
if (BreakPoint->Enabled)
|
||||||
{
|
{
|
||||||
KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
|
KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -793,6 +829,7 @@ KdbpEnableBreakPoint(
|
||||||
KDB_MAXIMUM_SW_BREAKPOINT_COUNT);
|
KDB_MAXIMUM_SW_BREAKPOINT_COUNT);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
|
Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
|
||||||
0xCC, &BreakPoint->Data.SavedInstruction);
|
0xCC, &BreakPoint->Data.SavedInstruction);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -800,18 +837,22 @@ KdbpEnableBreakPoint(
|
||||||
KdbpPrint("Couldn't access memory at 0x%p\n", BreakPoint->Address);
|
KdbpPrint("Couldn't access memory at 0x%p\n", BreakPoint->Address);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint;
|
KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (BreakPoint->Data.Hw.AccessType == KdbAccessExec)
|
if (BreakPoint->Data.Hw.AccessType == KdbAccessExec)
|
||||||
ASSERT(BreakPoint->Data.Hw.Size == 1);
|
ASSERT(BreakPoint->Data.Hw.Size == 1);
|
||||||
|
|
||||||
ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
|
ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
|
||||||
|
|
||||||
if (KdbHwBreakPointCount >= KDB_MAXIMUM_HW_BREAKPOINT_COUNT)
|
if (KdbHwBreakPointCount >= KDB_MAXIMUM_HW_BREAKPOINT_COUNT)
|
||||||
{
|
{
|
||||||
KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
|
KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
|
||||||
"Disable another breakpoint in order to enable this one.\n",
|
"Disable another breakpoint in order to enable this one.\n",
|
||||||
KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
|
KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,6 +863,7 @@ KdbpEnableBreakPoint(
|
||||||
if ((KdbTrapFrame.Tf.Dr7 & (0x3 << (i * 2))) == 0)
|
if ((KdbTrapFrame.Tf.Dr7 & (0x3 << (i * 2))) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
|
ASSERT(i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
|
||||||
|
|
||||||
/* Set the breakpoint address. */
|
/* Set the breakpoint address. */
|
||||||
|
@ -868,6 +910,7 @@ KdbpEnableBreakPoint(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbTrapFrame.Tf.Dr7 |= (ul << (16 + (i * 4)));
|
KdbTrapFrame.Tf.Dr7 |= (ul << (16 + (i * 4)));
|
||||||
|
|
||||||
/* Set the breakpoint length. */
|
/* Set the breakpoint length. */
|
||||||
|
@ -891,6 +934,7 @@ KdbpEnableBreakPoint(
|
||||||
BreakPoint->Enabled = TRUE;
|
BreakPoint->Enabled = TRUE;
|
||||||
if (BreakPoint->Type != KdbBreakPointTemporary)
|
if (BreakPoint->Type != KdbBreakPointTemporary)
|
||||||
KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
|
KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,18 +958,21 @@ KdbpDisableBreakPoint(
|
||||||
|
|
||||||
if (BreakPointNr < 0)
|
if (BreakPointNr < 0)
|
||||||
{
|
{
|
||||||
ASSERT(BreakPoint != NULL);
|
ASSERT(BreakPoint);
|
||||||
BreakPointNr = BreakPoint - KdbBreakPoints;
|
BreakPointNr = BreakPoint - KdbBreakPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
|
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
|
||||||
{
|
{
|
||||||
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (BreakPoint == NULL)
|
|
||||||
|
if (!BreakPoint)
|
||||||
{
|
{
|
||||||
BreakPoint = KdbBreakPoints + BreakPointNr;
|
BreakPoint = KdbBreakPoints + BreakPointNr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BreakPoint->Type == KdbBreakPointNone)
|
if (BreakPoint->Type == KdbBreakPointNone)
|
||||||
{
|
{
|
||||||
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
|
||||||
|
@ -944,6 +991,7 @@ KdbpDisableBreakPoint(
|
||||||
ASSERT(KdbSwBreakPointCount > 0);
|
ASSERT(KdbSwBreakPointCount > 0);
|
||||||
Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
|
Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
|
||||||
BreakPoint->Data.SavedInstruction, NULL);
|
BreakPoint->Data.SavedInstruction, NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KdbpPrint("Couldn't restore original instruction.\n");
|
KdbpPrint("Couldn't restore original instruction.\n");
|
||||||
|
@ -959,6 +1007,7 @@ KdbpDisableBreakPoint(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != (ULONG)-1) /* not found */
|
if (i != (ULONG)-1) /* not found */
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
@ -970,9 +1019,7 @@ KdbpDisableBreakPoint(
|
||||||
KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
|
KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
|
||||||
if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
|
if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
|
||||||
{
|
{
|
||||||
/*
|
/* If no breakpoints are enabled then clear the exact match flags. */
|
||||||
* If no breakpoints are enabled then clear the exact match flags.
|
|
||||||
*/
|
|
||||||
KdbTrapFrame.Tf.Dr7 &= 0xFFFFFCFF;
|
KdbTrapFrame.Tf.Dr7 &= 0xFFFFFCFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,6 +1032,7 @@ KdbpDisableBreakPoint(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != (ULONG)-1) /* not found */
|
if (i != (ULONG)-1) /* not found */
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
@ -992,6 +1040,7 @@ KdbpDisableBreakPoint(
|
||||||
BreakPoint->Enabled = FALSE;
|
BreakPoint->Enabled = FALSE;
|
||||||
if (BreakPoint->Type != KdbBreakPointTemporary)
|
if (BreakPoint->Type != KdbBreakPointTemporary)
|
||||||
KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
|
KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1041,6 +1090,7 @@ KdbpSetEnterCondition(
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
|
KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1052,8 +1102,10 @@ KdbpSetEnterCondition(
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
|
KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,8 +1142,7 @@ KdbpAttachToThread(
|
||||||
if (KdbCurrentThread != KdbOriginalThread)
|
if (KdbCurrentThread != KdbOriginalThread)
|
||||||
{
|
{
|
||||||
ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame);
|
ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame);
|
||||||
/* Actually, we can't save the context, there's no guarantee that there
|
/* Actually, we can't save the context, there's no guarantee that there was a trap frame */
|
||||||
* was a trap frame */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1124,10 +1175,12 @@ KdbpAttachToThread(
|
||||||
{
|
{
|
||||||
KeUnstackDetachProcess(&KdbApcState);
|
KeUnstackDetachProcess(&KdbApcState);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KdbOriginalProcess != Process)
|
if (KdbOriginalProcess != Process)
|
||||||
{
|
{
|
||||||
KeStackAttachProcess(&Process->Pcb, &KdbApcState);
|
KeStackAttachProcess(&Process->Pcb, &KdbApcState);
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbCurrentProcess = Process;
|
KdbCurrentProcess = Process;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,7 +1228,7 @@ KdbpAttachToProcess(
|
||||||
/*!\brief Calls the main loop ...
|
/*!\brief Calls the main loop ...
|
||||||
*/
|
*/
|
||||||
static VOID
|
static VOID
|
||||||
KdbpCallMainLoop(VOID)
|
KdbpCallMainLoop()
|
||||||
{
|
{
|
||||||
KdbpCliMainLoop(KdbEnteredOnSingleStep);
|
KdbpCliMainLoop(KdbEnteredOnSingleStep);
|
||||||
}
|
}
|
||||||
|
@ -1219,7 +1272,8 @@ KdbpInternalEnter()
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG
|
static ULONG
|
||||||
KdbpGetExceptionNumberFromStatus(IN NTSTATUS ExceptionCode)
|
KdbpGetExceptionNumberFromStatus(
|
||||||
|
IN NTSTATUS ExceptionCode)
|
||||||
{
|
{
|
||||||
ULONG Ret;
|
ULONG Ret;
|
||||||
|
|
||||||
|
@ -1298,7 +1352,7 @@ KdbEnterDebuggerException(
|
||||||
ULONG OldEflags;
|
ULONG OldEflags;
|
||||||
NTSTATUS ExceptionCode;
|
NTSTATUS ExceptionCode;
|
||||||
|
|
||||||
ExceptionCode = (ExceptionRecord != NULL ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT);
|
ExceptionCode = (ExceptionRecord ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT);
|
||||||
|
|
||||||
KdbCurrentProcess = PsGetCurrentProcess();
|
KdbCurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
|
@ -1328,9 +1382,7 @@ KdbEnterDebuggerException(
|
||||||
|
|
||||||
if (ExceptionCode == STATUS_BREAKPOINT)
|
if (ExceptionCode == STATUS_BREAKPOINT)
|
||||||
{
|
{
|
||||||
/*
|
/* ... and restore the original instruction. */
|
||||||
* ... and restore the original instruction.
|
|
||||||
*/
|
|
||||||
if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
|
if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
|
||||||
BreakPoint->Data.SavedInstruction, NULL)))
|
BreakPoint->Data.SavedInstruction, NULL)))
|
||||||
{
|
{
|
||||||
|
@ -1355,9 +1407,7 @@ KdbEnterDebuggerException(
|
||||||
{
|
{
|
||||||
ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
|
ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
|
||||||
|
|
||||||
/*
|
/* Delete the temporary breakpoint which was used to step over or into the instruction. */
|
||||||
* Delete the temporary breakpoint which was used to step over or into the instruction.
|
|
||||||
*/
|
|
||||||
KdbpDeleteBreakPoint(-1, BreakPoint);
|
KdbpDeleteBreakPoint(-1, BreakPoint);
|
||||||
|
|
||||||
if (--KdbNumSingleSteps > 0)
|
if (--KdbNumSingleSteps > 0)
|
||||||
|
@ -1367,6 +1417,7 @@ KdbEnterDebuggerException(
|
||||||
{
|
{
|
||||||
Context->EFlags |= EFLAGS_TF;
|
Context->EFlags |= EFLAGS_TF;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto continue_execution; /* return */
|
goto continue_execution; /* return */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1385,18 +1436,14 @@ KdbEnterDebuggerException(
|
||||||
KdbBreakPointToReenable = BreakPoint;
|
KdbBreakPointToReenable = BreakPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Make sure that the breakpoint should be triggered in this context */
|
||||||
* Make sure that the breakpoint should be triggered in this context
|
|
||||||
*/
|
|
||||||
if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess)
|
if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess)
|
||||||
{
|
{
|
||||||
goto continue_execution; /* return */
|
goto continue_execution; /* return */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Check if the condition for the breakpoint is met. */
|
||||||
* Check if the condition for the breakpoint is met.
|
if (BreakPoint->Condition)
|
||||||
*/
|
|
||||||
if (BreakPoint->Condition != NULL)
|
|
||||||
{
|
{
|
||||||
/* Setup the KDB trap frame */
|
/* Setup the KDB trap frame */
|
||||||
KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
|
KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
|
||||||
|
@ -1423,17 +1470,14 @@ KdbEnterDebuggerException(
|
||||||
KdbLastBreakPointNr,
|
KdbLastBreakPointNr,
|
||||||
(BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
|
(BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
|
||||||
((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
|
((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
|
||||||
((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")
|
((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")),
|
||||||
),
|
BreakPoint->Address);
|
||||||
BreakPoint->Address
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ExceptionCode == STATUS_SINGLE_STEP)
|
else if (ExceptionCode == STATUS_SINGLE_STEP)
|
||||||
{
|
{
|
||||||
/* Silently ignore a debugger initiated single step. */
|
/* Silently ignore a debugger initiated single step. */
|
||||||
if ((TrapFrame->Dr6 & 0xf) == 0 && KdbBreakPointToReenable != NULL)
|
if ((TrapFrame->Dr6 & 0xf) == 0 && KdbBreakPointToReenable)
|
||||||
{
|
{
|
||||||
/* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
|
/* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
|
||||||
BreakPoint = KdbBreakPointToReenable;
|
BreakPoint = KdbBreakPointToReenable;
|
||||||
|
@ -1455,6 +1499,7 @@ KdbEnterDebuggerException(
|
||||||
/* Unset TF if we are no longer single stepping. */
|
/* Unset TF if we are no longer single stepping. */
|
||||||
if (KdbNumSingleSteps == 0)
|
if (KdbNumSingleSteps == 0)
|
||||||
Context->EFlags &= ~EFLAGS_TF;
|
Context->EFlags &= ~EFLAGS_TF;
|
||||||
|
|
||||||
goto continue_execution; /* return */
|
goto continue_execution; /* return */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1473,6 +1518,7 @@ KdbEnterDebuggerException(
|
||||||
{
|
{
|
||||||
Context->EFlags |= EFLAGS_TF;
|
Context->EFlags |= EFLAGS_TF;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto continue_execution; /* return */
|
goto continue_execution; /* return */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1487,12 +1533,13 @@ KdbEnterDebuggerException(
|
||||||
{
|
{
|
||||||
return kdHandleException;
|
return kdHandleException;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbpPrint("Entered debugger on unexpected debug trap!\n");
|
KdbpPrint("Entered debugger on unexpected debug trap!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ExceptionCode == STATUS_BREAKPOINT)
|
else if (ExceptionCode == STATUS_BREAKPOINT)
|
||||||
{
|
{
|
||||||
if (KdbInitFileBuffer != NULL)
|
if (KdbInitFileBuffer)
|
||||||
{
|
{
|
||||||
KdbpCliInterpretInitFile();
|
KdbpCliInterpretInitFile();
|
||||||
EnterConditionMet = FALSE;
|
EnterConditionMet = FALSE;
|
||||||
|
@ -1518,12 +1565,14 @@ KdbEnterDebuggerException(
|
||||||
|
|
||||||
KdbpPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
|
KdbpPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
|
||||||
FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
|
FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
|
||||||
|
|
||||||
if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
|
if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
|
||||||
ExceptionRecord != NULL && ExceptionRecord->NumberParameters != 0)
|
ExceptionRecord && ExceptionRecord->NumberParameters != 0)
|
||||||
{
|
{
|
||||||
/* FIXME: Add noexec memory stuff */
|
/* FIXME: Add noexec memory stuff */
|
||||||
ULONG_PTR TrapCr2;
|
ULONG_PTR TrapCr2;
|
||||||
ULONG Err;
|
ULONG Err;
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
asm volatile("movl %%cr2, %0" : "=r"(TrapCr2));
|
asm volatile("movl %%cr2, %0" : "=r"(TrapCr2));
|
||||||
#elif _MSC_VER
|
#elif _MSC_VER
|
||||||
|
@ -1535,8 +1584,11 @@ KdbEnterDebuggerException(
|
||||||
|
|
||||||
Err = TrapFrame->ErrCode;
|
Err = TrapFrame->ErrCode;
|
||||||
KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
|
KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
|
||||||
|
|
||||||
if ((Err & (1 << 0)) == 0)
|
if ((Err & (1 << 0)) == 0)
|
||||||
|
{
|
||||||
KdbpPrint("Page not present.\n");
|
KdbpPrint("Page not present.\n");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((Err & (1 << 3)) != 0)
|
if ((Err & (1 << 3)) != 0)
|
||||||
|
@ -1587,8 +1639,7 @@ KdbEnterDebuggerException(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can't update the current thread's trapframe 'cause it might not
|
/* We can't update the current thread's trapframe 'cause it might not have one */
|
||||||
have one */
|
|
||||||
|
|
||||||
/* Detach from attached process */
|
/* Detach from attached process */
|
||||||
if (KdbCurrentProcess != KdbOriginalProcess)
|
if (KdbCurrentProcess != KdbOriginalProcess)
|
||||||
|
@ -1634,7 +1685,8 @@ continue_execution:
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbDeleteProcessHook(IN PEPROCESS Process)
|
KdbDeleteProcessHook(
|
||||||
|
IN PEPROCESS Process)
|
||||||
{
|
{
|
||||||
KdbSymFreeProcessSymbols(Process);
|
KdbSymFreeProcessSymbols(Process);
|
||||||
|
|
||||||
|
@ -1643,7 +1695,8 @@ KdbDeleteProcessHook(IN PEPROCESS Process)
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdbpGetCommandLineSettings(PCHAR p1)
|
KdbpGetCommandLineSettings(
|
||||||
|
PCHAR p1)
|
||||||
{
|
{
|
||||||
PCHAR p2;
|
PCHAR p2;
|
||||||
|
|
||||||
|
@ -1668,7 +1721,8 @@ KdbpGetCommandLineSettings(PCHAR p1)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
KdbpSafeReadMemory(OUT PVOID Dest,
|
KdbpSafeReadMemory(
|
||||||
|
OUT PVOID Dest,
|
||||||
IN PVOID Src,
|
IN PVOID Src,
|
||||||
IN ULONG Bytes)
|
IN ULONG Bytes)
|
||||||
{
|
{
|
||||||
|
@ -1682,9 +1736,11 @@ KdbpSafeReadMemory(OUT PVOID Dest,
|
||||||
case 8:
|
case 8:
|
||||||
Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
|
Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ULONG_PTR Start, End, Write;
|
ULONG_PTR Start, End, Write;
|
||||||
|
|
||||||
for (Start = (ULONG_PTR)Src,
|
for (Start = (ULONG_PTR)Src,
|
||||||
End = Start + Bytes,
|
End = Start + Bytes,
|
||||||
Write = (ULONG_PTR)Dest;
|
Write = (ULONG_PTR)Dest;
|
||||||
|
@ -1692,6 +1748,7 @@ KdbpSafeReadMemory(OUT PVOID Dest,
|
||||||
Start++, Write++)
|
Start++, Write++)
|
||||||
if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
|
if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
|
||||||
Result = FALSE;
|
Result = FALSE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1700,7 +1757,8 @@ KdbpSafeReadMemory(OUT PVOID Dest,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
KdbpSafeWriteMemory(OUT PVOID Dest,
|
KdbpSafeWriteMemory(
|
||||||
|
OUT PVOID Dest,
|
||||||
IN PVOID Src,
|
IN PVOID Src,
|
||||||
IN ULONG Bytes)
|
IN ULONG Bytes)
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -54,7 +54,8 @@ typedef struct _RPN_OP
|
||||||
{
|
{
|
||||||
RPN_OP_TYPE Type;
|
RPN_OP_TYPE Type;
|
||||||
ULONG CharacterOffset;
|
ULONG CharacterOffset;
|
||||||
union {
|
union
|
||||||
|
{
|
||||||
/* RpnOpBinaryOperator */
|
/* RpnOpBinaryOperator */
|
||||||
RPN_BINARY_OPERATOR BinaryOperator;
|
RPN_BINARY_OPERATOR BinaryOperator;
|
||||||
/* RpnOpImmediate */
|
/* RpnOpImmediate */
|
||||||
|
@ -63,15 +64,18 @@ typedef struct _RPN_OP
|
||||||
UCHAR Register;
|
UCHAR Register;
|
||||||
/* RpnOpDereference */
|
/* RpnOpDereference */
|
||||||
UCHAR DerefMemorySize;
|
UCHAR DerefMemorySize;
|
||||||
} Data;
|
}
|
||||||
} RPN_OP, *PRPN_OP;
|
Data;
|
||||||
|
}
|
||||||
|
RPN_OP, *PRPN_OP;
|
||||||
|
|
||||||
typedef struct _RPN_STACK
|
typedef struct _RPN_STACK
|
||||||
{
|
{
|
||||||
ULONG Size; /* Number of RPN_OPs on Ops */
|
ULONG Size; /* Number of RPN_OPs on Ops */
|
||||||
ULONG Sp; /* Stack pointer */
|
ULONG Sp; /* Stack pointer */
|
||||||
RPN_OP Ops[1]; /* Array of RPN_OPs */
|
RPN_OP Ops[1]; /* Array of RPN_OPs */
|
||||||
} RPN_STACK, *PRPN_STACK;
|
}
|
||||||
|
RPN_STACK, *PRPN_STACK;
|
||||||
|
|
||||||
/* DEFINES *******************************************************************/
|
/* DEFINES *******************************************************************/
|
||||||
#define stricmp _stricmp
|
#define stricmp _stricmp
|
||||||
|
@ -81,15 +85,31 @@ typedef struct _RPN_STACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONST_STRCPY(dst, src) \
|
#define CONST_STRCPY(dst, src) \
|
||||||
do { if ((dst) != NULL) { memcpy(dst, src, sizeof(src)); } } while (0);
|
do { if ((dst)) { memcpy(dst, src, sizeof(src)); } } while (0);
|
||||||
|
|
||||||
#define RPN_OP_STACK_SIZE 256
|
#define RPN_OP_STACK_SIZE 256
|
||||||
#define RPN_VALUE_STACK_SIZE 256
|
#define RPN_VALUE_STACK_SIZE 256
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
static struct { ULONG Size; ULONG Sp; RPN_OP Ops[RPN_OP_STACK_SIZE]; } RpnStack = { RPN_OP_STACK_SIZE, 0 };
|
static struct
|
||||||
|
{
|
||||||
|
ULONG Size;
|
||||||
|
ULONG Sp;
|
||||||
|
RPN_OP Ops[RPN_OP_STACK_SIZE];
|
||||||
|
}
|
||||||
|
RpnStack =
|
||||||
|
{
|
||||||
|
RPN_OP_STACK_SIZE,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
static const struct { PCHAR Name; UCHAR Offset; UCHAR Size; } RegisterToTrapFrame[] =
|
static const struct
|
||||||
|
{
|
||||||
|
PCHAR Name;
|
||||||
|
UCHAR Offset;
|
||||||
|
UCHAR Size;
|
||||||
|
}
|
||||||
|
RegisterToTrapFrame[] =
|
||||||
{
|
{
|
||||||
{"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eip)},
|
{"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eip)},
|
||||||
{"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.EFlags)},
|
{"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.EFlags)},
|
||||||
|
@ -118,74 +138,94 @@ static const struct { PCHAR Name; UCHAR Offset; UCHAR Size; } RegisterToTrapFram
|
||||||
{"cr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr3)},
|
{"cr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr3)},
|
||||||
{"cr4", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr4), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr4)}
|
{"cr4", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr4), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr4)}
|
||||||
};
|
};
|
||||||
static const INT RegisterToTrapFrameCount =
|
static const INT RegisterToTrapFrameCount = sizeof (RegisterToTrapFrame) / sizeof (RegisterToTrapFrame[0]);
|
||||||
sizeof (RegisterToTrapFrame) / sizeof (RegisterToTrapFrame[0]);
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorAdd(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorAdd(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorSub(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorSub(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return a - b;
|
return a - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorMul(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorMul(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return a * b;
|
return a * b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorDiv(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorDiv(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
|
|
||||||
return a / b;
|
return a / b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorMod(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorMod(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return a % b;
|
return a % b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorEquals(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorEquals(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return (a == b);
|
return (a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorNotEquals(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorNotEquals(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return (a != b);
|
return (a != b);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorLessThan(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorLessThan(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return (a < b);
|
return (a < b);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorLessThanOrEquals(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorLessThanOrEquals(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return (a <= b);
|
return (a <= b);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorGreaterThan(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorGreaterThan(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return (a > b);
|
return (a > b);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
RpnBinaryOperatorGreaterThanOrEquals(ULONGLONG a, ULONGLONG b)
|
RpnBinaryOperatorGreaterThanOrEquals(
|
||||||
|
ULONGLONG a,
|
||||||
|
ULONGLONG b)
|
||||||
{
|
{
|
||||||
return (a >= b);
|
return (a >= b);
|
||||||
}
|
}
|
||||||
|
@ -200,8 +240,9 @@ RpnpDumpStack(
|
||||||
{
|
{
|
||||||
ULONG ul;
|
ULONG ul;
|
||||||
|
|
||||||
ASSERT(Stack != NULL);
|
ASSERT(Stack);
|
||||||
DbgPrint("\nStack size: %ld\n", Stack->Sp);
|
DbgPrint("\nStack size: %ld\n", Stack->Sp);
|
||||||
|
|
||||||
for (ul = 0; ul < Stack->Sp; ul++)
|
for (ul = 0; ul < Stack->Sp; ul++)
|
||||||
{
|
{
|
||||||
PRPN_OP Op = Stack->Ops + ul;
|
PRPN_OP Op = Stack->Ops + ul;
|
||||||
|
@ -240,6 +281,7 @@ RpnpDumpStack(
|
||||||
DbgPrint(">=,");
|
DbgPrint(">=,");
|
||||||
else
|
else
|
||||||
DbgPrint("UNKNOWN OP,");
|
DbgPrint("UNKNOWN OP,");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RpnOpRegister:
|
case RpnOpRegister:
|
||||||
|
@ -250,9 +292,7 @@ RpnpDumpStack(
|
||||||
DbgPrint("[%s],",
|
DbgPrint("[%s],",
|
||||||
(Op->Data.DerefMemorySize == 1) ? ("byte") :
|
(Op->Data.DerefMemorySize == 1) ? ("byte") :
|
||||||
((Op->Data.DerefMemorySize == 2) ? ("word") :
|
((Op->Data.DerefMemorySize == 2) ? ("word") :
|
||||||
((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword"))
|
((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword"))));
|
||||||
)
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -261,6 +301,7 @@ RpnpDumpStack(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("\n");
|
DbgPrint("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +313,7 @@ static VOID
|
||||||
RpnpClearStack(
|
RpnpClearStack(
|
||||||
OUT PRPN_STACK Stack)
|
OUT PRPN_STACK Stack)
|
||||||
{
|
{
|
||||||
ASSERT(Stack != NULL);
|
ASSERT(Stack);
|
||||||
Stack->Sp = 0;
|
Stack->Sp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,14 +327,15 @@ RpnpPushStack(
|
||||||
IN OUT PRPN_STACK Stack,
|
IN OUT PRPN_STACK Stack,
|
||||||
IN PRPN_OP Op)
|
IN PRPN_OP Op)
|
||||||
{
|
{
|
||||||
ASSERT(Stack != NULL);
|
ASSERT(Stack);
|
||||||
ASSERT(Op != NULL);
|
ASSERT(Op);
|
||||||
|
|
||||||
if (Stack->Sp >= Stack->Size)
|
if (Stack->Sp >= Stack->Size)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP));
|
memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP));
|
||||||
Stack->Sp++;
|
Stack->Sp++;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,14 +352,15 @@ RpnpPopStack(
|
||||||
IN OUT PRPN_STACK Stack,
|
IN OUT PRPN_STACK Stack,
|
||||||
OUT PRPN_OP Op OPTIONAL)
|
OUT PRPN_OP Op OPTIONAL)
|
||||||
{
|
{
|
||||||
ASSERT(Stack != NULL);
|
ASSERT(Stack);
|
||||||
|
|
||||||
if (Stack->Sp == 0)
|
if (Stack->Sp == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
Stack->Sp--;
|
Stack->Sp--;
|
||||||
if (Op != NULL)
|
if (Op)
|
||||||
memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP));
|
memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,13 +377,14 @@ RpnpTopStack(
|
||||||
IN PRPN_STACK Stack,
|
IN PRPN_STACK Stack,
|
||||||
OUT PRPN_OP Op)
|
OUT PRPN_OP Op)
|
||||||
{
|
{
|
||||||
ASSERT(Stack != NULL);
|
ASSERT(Stack);
|
||||||
ASSERT(Op != NULL);
|
ASSERT(Op);
|
||||||
|
|
||||||
if (Stack->Sp == 0)
|
if (Stack->Sp == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP));
|
memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,8 +431,8 @@ RpnpParseExpression(
|
||||||
CHAR Buffer[16];
|
CHAR Buffer[16];
|
||||||
BOOLEAN First;
|
BOOLEAN First;
|
||||||
|
|
||||||
ASSERT(Stack != NULL);
|
ASSERT(Stack);
|
||||||
ASSERT(Expression != NULL);
|
ASSERT(Expression);
|
||||||
|
|
||||||
First = TRUE;
|
First = TRUE;
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -451,18 +495,23 @@ RpnpParseExpression(
|
||||||
else if (pend == p + 1)
|
else if (pend == p + 1)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Expression expected");
|
CONST_STRCPY(ErrMsg, "Expression expected");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = CharacterOffset + 1;
|
*ErrOffset = CharacterOffset + 1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto end_of_expression; /* return */
|
goto end_of_expression; /* return */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (Operator[0] != '+' && Operator[0] != '-')
|
else if (Operator[0] != '+' && Operator[0] != '-')
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Operator expected");
|
CONST_STRCPY(ErrMsg, "Operator expected");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = OperatorOffset;
|
*ErrOffset = OperatorOffset;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +525,7 @@ RpnpParseExpression(
|
||||||
|
|
||||||
/* Get operand */
|
/* Get operand */
|
||||||
MemorySize = sizeof(ULONG_PTR); /* default to pointer size */
|
MemorySize = sizeof(ULONG_PTR); /* default to pointer size */
|
||||||
|
|
||||||
get_operand:
|
get_operand:
|
||||||
i = strcspn(p, "+-*/%()[]<>!=");
|
i = strcspn(p, "+-*/%()[]<>!=");
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
|
@ -484,6 +534,7 @@ get_operand:
|
||||||
|
|
||||||
/* Copy register name/memory size */
|
/* Copy register name/memory size */
|
||||||
while (isspace(p[--i2]));
|
while (isspace(p[--i2]));
|
||||||
|
|
||||||
i2 = min(i2 + 1, (INT)sizeof (Buffer) - 1);
|
i2 = min(i2 + 1, (INT)sizeof (Buffer) - 1);
|
||||||
strncpy(Buffer, p, i2);
|
strncpy(Buffer, p, i2);
|
||||||
Buffer[i2] = '\0';
|
Buffer[i2] = '\0';
|
||||||
|
@ -502,8 +553,10 @@ get_operand:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Invalid memory size prefix");
|
CONST_STRCPY(ErrMsg, "Invalid memory size prefix");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = CharacterOffset;
|
*ErrOffset = CharacterOffset;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,6 +571,7 @@ get_operand:
|
||||||
if (stricmp(RegisterToTrapFrame[i].Name, Buffer) == 0)
|
if (stricmp(RegisterToTrapFrame[i].Name, Buffer) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < RegisterToTrapFrameCount)
|
if (i < RegisterToTrapFrameCount)
|
||||||
{
|
{
|
||||||
RpnOp.Type = RpnOpRegister;
|
RpnOp.Type = RpnOpRegister;
|
||||||
|
@ -543,8 +597,10 @@ get_operand:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Operand expected");
|
CONST_STRCPY(ErrMsg, "Operand expected");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = CharacterOffset;
|
*ErrOffset = CharacterOffset;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,8 +609,10 @@ get_operand:
|
||||||
if (!RpnpPushStack(Stack, &RpnOp))
|
if (!RpnpPushStack(Stack, &RpnOp))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -570,8 +628,10 @@ get_operand:
|
||||||
else if (pend == p + 1)
|
else if (pend == p + 1)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Expression expected");
|
CONST_STRCPY(ErrMsg, "Expression expected");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = CharacterOffset + 1;
|
*ErrOffset = CharacterOffset + 1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,21 +639,28 @@ get_operand:
|
||||||
{
|
{
|
||||||
ASSERT(MemorySize == 1 || MemorySize == 2 ||
|
ASSERT(MemorySize == 1 || MemorySize == 2 ||
|
||||||
MemorySize == 4 || MemorySize == 8);
|
MemorySize == 4 || MemorySize == 8);
|
||||||
|
|
||||||
if (pend[0] != ']')
|
if (pend[0] != ']')
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "']' expected");
|
CONST_STRCPY(ErrMsg, "']' expected");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = CharacterOffset + (pend - p);
|
*ErrOffset = CharacterOffset + (pend - p);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RpnOp.Type = RpnOpDereference;
|
RpnOp.Type = RpnOpDereference;
|
||||||
RpnOp.CharacterOffset = CharacterOffset;
|
RpnOp.CharacterOffset = CharacterOffset;
|
||||||
RpnOp.Data.DerefMemorySize = MemorySize;
|
RpnOp.Data.DerefMemorySize = MemorySize;
|
||||||
|
|
||||||
if (!RpnpPushStack(Stack, &RpnOp))
|
if (!RpnpPushStack(Stack, &RpnOp))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -602,8 +669,10 @@ get_operand:
|
||||||
if (pend[0] != ')')
|
if (pend[0] != ')')
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "')' expected");
|
CONST_STRCPY(ErrMsg, "')' expected");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = CharacterOffset + (pend - p);
|
*ErrOffset = CharacterOffset + (pend - p);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -615,8 +684,10 @@ get_operand:
|
||||||
if (!RpnpPushStack(Stack, &RpnOp))
|
if (!RpnpPushStack(Stack, &RpnOp))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,27 +702,34 @@ get_operand:
|
||||||
RpnOp.Type = RpnOpImmediate;
|
RpnOp.Type = RpnOpImmediate;
|
||||||
RpnOp.CharacterOffset = CharacterOffset;
|
RpnOp.CharacterOffset = CharacterOffset;
|
||||||
RpnOp.Data.Immediate = 0;
|
RpnOp.Data.Immediate = 0;
|
||||||
|
|
||||||
if (!RpnpPushStack(Stack, &RpnOp))
|
if (!RpnpPushStack(Stack, &RpnOp))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Operand expected");
|
CONST_STRCPY(ErrMsg, "Operand expected");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = CharacterOffset;
|
*ErrOffset = CharacterOffset;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "strcspn() failed");
|
CONST_STRCPY(ErrMsg, "strcspn() failed");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,6 +739,7 @@ get_operand:
|
||||||
RpnOp.CharacterOffset = OperatorOffset;
|
RpnOp.CharacterOffset = OperatorOffset;
|
||||||
RpnOp.Type = RpnOpBinaryOperator;
|
RpnOp.Type = RpnOpBinaryOperator;
|
||||||
IsComparativeOp = FALSE;
|
IsComparativeOp = FALSE;
|
||||||
|
|
||||||
switch (*Operator)
|
switch (*Operator)
|
||||||
{
|
{
|
||||||
case '+':
|
case '+':
|
||||||
|
@ -697,41 +776,51 @@ get_operand:
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
IsComparativeOp = TRUE;
|
IsComparativeOp = TRUE;
|
||||||
|
|
||||||
if (Operator[1] == '=')
|
if (Operator[1] == '=')
|
||||||
RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThanOrEquals;
|
RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThanOrEquals;
|
||||||
else
|
else
|
||||||
RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThan;
|
RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThan;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
IsComparativeOp = TRUE;
|
IsComparativeOp = TRUE;
|
||||||
|
|
||||||
if (Operator[1] == '=')
|
if (Operator[1] == '=')
|
||||||
RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThanOrEquals;
|
RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThanOrEquals;
|
||||||
else
|
else
|
||||||
RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThan;
|
RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThan;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsComparativeOp)
|
if (IsComparativeOp)
|
||||||
{
|
{
|
||||||
if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
|
if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP));
|
memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP));
|
||||||
ComparativeOpFilled = TRUE;
|
ComparativeOpFilled = TRUE;
|
||||||
}
|
}
|
||||||
else if (!RpnpPushStack(Stack, &RpnOp))
|
else if (!RpnpPushStack(Stack, &RpnOp))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,8 +830,10 @@ get_operand:
|
||||||
if (!RpnpPushStack(Stack, &PoppedOperator))
|
if (!RpnpPushStack(Stack, &PoppedOperator))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -756,8 +847,10 @@ get_operand:
|
||||||
if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
|
if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
CONST_STRCPY(ErrMsg, "RPN op stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,7 +861,7 @@ get_operand:
|
||||||
CharacterOffset++;
|
CharacterOffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (End != NULL)
|
if (End)
|
||||||
*End = p;
|
*End = p;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -806,9 +899,9 @@ RpnpEvaluateStack(
|
||||||
ULONG ValueStackPointerMax = 0;
|
ULONG ValueStackPointerMax = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASSERT(Stack != NULL);
|
ASSERT(Stack);
|
||||||
ASSERT(TrapFrame != NULL);
|
ASSERT(TrapFrame);
|
||||||
ASSERT(Result != NULL);
|
ASSERT(Result);
|
||||||
|
|
||||||
for (index = 0; index < Stack->Sp; index++)
|
for (index = 0; index < Stack->Sp; index++)
|
||||||
{
|
{
|
||||||
|
@ -828,10 +921,13 @@ RpnpEvaluateStack(
|
||||||
if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
|
if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Value stack overflow");
|
CONST_STRCPY(ErrMsg, "Value stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueStack[ValueStackPointer++] = Op->Data.Immediate;
|
ValueStack[ValueStackPointer++] = Op->Data.Immediate;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -839,12 +935,16 @@ RpnpEvaluateStack(
|
||||||
if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
|
if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Value stack overflow");
|
CONST_STRCPY(ErrMsg, "Value stack overflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul = Op->Data.Register;
|
ul = Op->Data.Register;
|
||||||
p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset);
|
p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset);
|
||||||
|
|
||||||
switch (RegisterToTrapFrame[ul].Size)
|
switch (RegisterToTrapFrame[ul].Size)
|
||||||
{
|
{
|
||||||
case 1: ull = (ULONGLONG)(*(PUCHAR)p); break;
|
case 1: ull = (ULONGLONG)(*(PUCHAR)p); break;
|
||||||
|
@ -853,6 +953,7 @@ RpnpEvaluateStack(
|
||||||
case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break;
|
case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break;
|
||||||
default: ASSERT(0); return FALSE; break;
|
default: ASSERT(0); return FALSE; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueStack[ValueStackPointer++] = ull;
|
ValueStack[ValueStackPointer++] = ull;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -860,14 +961,17 @@ RpnpEvaluateStack(
|
||||||
if (ValueStackPointer < 1)
|
if (ValueStackPointer < 1)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Value stack underflow");
|
CONST_STRCPY(ErrMsg, "Value stack underflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Print a warning when address is out of range */
|
/* FIXME: Print a warning when address is out of range */
|
||||||
p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1];
|
p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1];
|
||||||
Ok = FALSE;
|
Ok = FALSE;
|
||||||
|
|
||||||
switch (Op->Data.DerefMemorySize)
|
switch (Op->Data.DerefMemorySize)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -877,6 +981,7 @@ RpnpEvaluateStack(
|
||||||
ull = (ULONGLONG)uc;
|
ull = (ULONGLONG)uc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us))))
|
if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us))))
|
||||||
{
|
{
|
||||||
|
@ -884,6 +989,7 @@ RpnpEvaluateStack(
|
||||||
ull = (ULONGLONG)us;
|
ull = (ULONGLONG)us;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul))))
|
if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul))))
|
||||||
{
|
{
|
||||||
|
@ -891,24 +997,30 @@ RpnpEvaluateStack(
|
||||||
ull = (ULONGLONG)ul;
|
ull = (ULONGLONG)ul;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull))))
|
if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull))))
|
||||||
{
|
{
|
||||||
Ok = TRUE;
|
Ok = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Ok)
|
if (!Ok)
|
||||||
{
|
{
|
||||||
_snprintf(ErrMsg, 128, "Couldn't access memory at 0x%lx", (ULONG)p);
|
_snprintf(ErrMsg, 128, "Couldn't access memory at 0x%lx", (ULONG)p);
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = Op->CharacterOffset;
|
*ErrOffset = Op->CharacterOffset;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueStack[ValueStackPointer - 1] = ull;
|
ValueStack[ValueStackPointer - 1] = ull;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -916,20 +1028,27 @@ RpnpEvaluateStack(
|
||||||
if (ValueStackPointer < 2)
|
if (ValueStackPointer < 2)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Value stack underflow");
|
CONST_STRCPY(ErrMsg, "Value stack underflow");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueStackPointer--;
|
ValueStackPointer--;
|
||||||
ull = ValueStack[ValueStackPointer];
|
ull = ValueStack[ValueStackPointer];
|
||||||
|
|
||||||
if (ull == 0 && (Op->Data.BinaryOperator == RpnBinaryOperatorDiv ||
|
if (ull == 0 && (Op->Data.BinaryOperator == RpnBinaryOperatorDiv ||
|
||||||
Op->Data.BinaryOperator == RpnBinaryOperatorDiv))
|
Op->Data.BinaryOperator == RpnBinaryOperatorDiv))
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Devision by zero");
|
CONST_STRCPY(ErrMsg, "Devision by zero");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = Op->CharacterOffset;
|
*ErrOffset = Op->CharacterOffset;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull);
|
ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull);
|
||||||
ValueStack[ValueStackPointer - 1] = ull;
|
ValueStack[ValueStackPointer - 1] = ull;
|
||||||
break;
|
break;
|
||||||
|
@ -939,14 +1058,18 @@ RpnpEvaluateStack(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_RPN
|
#ifdef DEBUG_RPN
|
||||||
DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax);
|
DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ValueStackPointer != 1)
|
if (ValueStackPointer != 1)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Stack not empty after evaluation");
|
CONST_STRCPY(ErrMsg, "Stack not empty after evaluation");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,25 +1098,22 @@ KdbpRpnEvaluateExpression(
|
||||||
{
|
{
|
||||||
PRPN_STACK Stack = (PRPN_STACK)&RpnStack;
|
PRPN_STACK Stack = (PRPN_STACK)&RpnStack;
|
||||||
|
|
||||||
ASSERT(Expression != NULL);
|
ASSERT(Expression);
|
||||||
ASSERT(TrapFrame != NULL);
|
ASSERT(TrapFrame);
|
||||||
ASSERT(Result != NULL);
|
ASSERT(Result);
|
||||||
|
|
||||||
/* Clear the stack and parse the expression */
|
/* Clear the stack and parse the expression */
|
||||||
RpnpClearStack(Stack);
|
RpnpClearStack(Stack);
|
||||||
if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
|
if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
#ifdef DEBUG_RPN
|
#ifdef DEBUG_RPN
|
||||||
RpnpDumpStack(Stack);
|
RpnpDumpStack(Stack);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Evaluate the stack */
|
/* Evaluate the stack */
|
||||||
if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg))
|
if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg))
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1018,14 +1138,13 @@ KdbpRpnParseExpression(
|
||||||
PRPN_STACK Stack = (PRPN_STACK)&RpnStack;
|
PRPN_STACK Stack = (PRPN_STACK)&RpnStack;
|
||||||
PRPN_STACK NewStack;
|
PRPN_STACK NewStack;
|
||||||
|
|
||||||
ASSERT(Expression != NULL);
|
ASSERT(Expression);
|
||||||
|
|
||||||
/* Clear the stack and parse the expression */
|
/* Clear the stack and parse the expression */
|
||||||
RpnpClearStack(Stack);
|
RpnpClearStack(Stack);
|
||||||
if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
|
if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
#ifdef DEBUG_RPN
|
#ifdef DEBUG_RPN
|
||||||
RpnpDumpStack(Stack);
|
RpnpDumpStack(Stack);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1034,13 +1153,17 @@ KdbpRpnParseExpression(
|
||||||
ASSERT(Stack->Sp >= 1);
|
ASSERT(Stack->Sp >= 1);
|
||||||
Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1));
|
Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1));
|
||||||
NewStack = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_KDBG);
|
NewStack = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_KDBG);
|
||||||
if (NewStack == NULL)
|
|
||||||
|
if (!NewStack)
|
||||||
{
|
{
|
||||||
CONST_STRCPY(ErrMsg, "Out of memory");
|
CONST_STRCPY(ErrMsg, "Out of memory");
|
||||||
if (ErrOffset != NULL)
|
|
||||||
|
if (ErrOffset)
|
||||||
*ErrOffset = -1;
|
*ErrOffset = -1;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(NewStack, Stack, Size);
|
memcpy(NewStack, Stack, Size);
|
||||||
NewStack->Size = NewStack->Sp;
|
NewStack->Size = NewStack->Sp;
|
||||||
|
|
||||||
|
@ -1069,9 +1192,9 @@ KdbpRpnEvaluateParsedExpression(
|
||||||
{
|
{
|
||||||
PRPN_STACK Stack = (PRPN_STACK)Expression;
|
PRPN_STACK Stack = (PRPN_STACK)Expression;
|
||||||
|
|
||||||
ASSERT(Expression != NULL);
|
ASSERT(Expression);
|
||||||
ASSERT(TrapFrame != NULL);
|
ASSERT(TrapFrame);
|
||||||
ASSERT(Result != NULL);
|
ASSERT(Result);
|
||||||
|
|
||||||
/* Evaluate the stack */
|
/* Evaluate the stack */
|
||||||
return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg);
|
return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg);
|
||||||
|
|
|
@ -86,6 +86,7 @@ KbdSendCommandToMouse(UCHAR Command)
|
||||||
KeStallExecutionProcessor(50);
|
KeStallExecutionProcessor(50);
|
||||||
|
|
||||||
if (kbd_read_input() != MOUSE_ACK) { ; }
|
if (kbd_read_input() != MOUSE_ACK) { ; }
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,27 +109,38 @@ KdbpTryGetCharKeyboard(PULONG ScanCode, ULONG Retry)
|
||||||
static byte_t shift = 0;
|
static byte_t shift = 0;
|
||||||
char c;
|
char c;
|
||||||
BOOLEAN KeepRetrying = (Retry == 0);
|
BOOLEAN KeepRetrying = (Retry == 0);
|
||||||
while (KeepRetrying || Retry-- > 0) {
|
|
||||||
|
while (KeepRetrying || Retry-- > 0)
|
||||||
|
{
|
||||||
unsigned char status = kbd_read_status();
|
unsigned char status = kbd_read_status();
|
||||||
while (status & KBD_STAT_OBF) {
|
|
||||||
|
while (status & KBD_STAT_OBF)
|
||||||
|
{
|
||||||
byte_t scancode;
|
byte_t scancode;
|
||||||
|
|
||||||
scancode = kbd_read_input();
|
scancode = kbd_read_input();
|
||||||
|
|
||||||
/* check for SHIFT-keys */
|
/* check for SHIFT-keys */
|
||||||
if (((scancode & 0x7F) == 42) || ((scancode & 0x7F) == 54))
|
if (((scancode & 0x7F) == 42) || ((scancode & 0x7F) == 54))
|
||||||
{
|
{
|
||||||
shift = !(scancode & 0x80);
|
shift = !(scancode & 0x80);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ignore all other RELEASED-codes */
|
/* ignore all other RELEASED-codes */
|
||||||
if (scancode & 0x80)
|
if (scancode & 0x80)
|
||||||
|
{
|
||||||
last_key = 0;
|
last_key = 0;
|
||||||
|
}
|
||||||
else if (last_key != scancode)
|
else if (last_key != scancode)
|
||||||
{
|
{
|
||||||
//printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[shift][scancode]);
|
//printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[shift][scancode]);
|
||||||
last_key = scancode;
|
last_key = scancode;
|
||||||
c = keyb_layout[shift][scancode];
|
c = keyb_layout[shift][scancode];
|
||||||
*ScanCode = scancode;
|
*ScanCode = scancode;
|
||||||
if (c > 0) return c;
|
|
||||||
|
if (c > 0)
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,14 @@
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
typedef struct _IMAGE_SYMBOL_INFO_CACHE {
|
typedef struct _IMAGE_SYMBOL_INFO_CACHE
|
||||||
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
ULONG RefCount;
|
ULONG RefCount;
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
PROSSYM_INFO RosSymInfo;
|
PROSSYM_INFO RosSymInfo;
|
||||||
} IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE;
|
}
|
||||||
|
IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE;
|
||||||
|
|
||||||
static BOOLEAN LoadSymbols;
|
static BOOLEAN LoadSymbols;
|
||||||
static LIST_ENTRY SymbolFileListHead;
|
static LIST_ENTRY SymbolFileListHead;
|
||||||
|
@ -45,7 +47,8 @@ BOOLEAN KdbpSymbolsInitialized = FALSE;
|
||||||
* \sa KdbpSymFindModule
|
* \sa KdbpSymFindModule
|
||||||
*/
|
*/
|
||||||
static BOOLEAN
|
static BOOLEAN
|
||||||
KdbpSymFindUserModule(IN PVOID Address OPTIONAL,
|
KdbpSymFindUserModule(
|
||||||
|
IN PVOID Address OPTIONAL,
|
||||||
IN LPCWSTR Name OPTIONAL,
|
IN LPCWSTR Name OPTIONAL,
|
||||||
IN INT Index OPTIONAL,
|
IN INT Index OPTIONAL,
|
||||||
OUT PKDB_MODULE_INFO pInfo)
|
OUT PKDB_MODULE_INFO pInfo)
|
||||||
|
@ -61,26 +64,21 @@ KdbpSymFindUserModule(IN PVOID Address OPTIONAL,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
if (CurrentProcess != NULL)
|
if (CurrentProcess)
|
||||||
{
|
|
||||||
Peb = CurrentProcess->Peb;
|
Peb = CurrentProcess->Peb;
|
||||||
}
|
|
||||||
|
|
||||||
if (Peb == NULL || Peb->Ldr == NULL)
|
if (!Peb || !Peb->Ldr)
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
current_entry = Peb->Ldr->InLoadOrderModuleList.Flink;
|
current_entry = Peb->Ldr->InLoadOrderModuleList.Flink;
|
||||||
|
|
||||||
while (current_entry != &Peb->Ldr->InLoadOrderModuleList &&
|
while (current_entry != &Peb->Ldr->InLoadOrderModuleList && current_entry)
|
||||||
current_entry != NULL)
|
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||||
Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255);
|
Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255);
|
||||||
if ((Address != NULL && (Address >= (PVOID)current->DllBase &&
|
if ((Address && (Address >= (PVOID)current->DllBase &&
|
||||||
Address < (PVOID)((char *)current->DllBase + current->SizeOfImage))) ||
|
Address < (PVOID)((char *)current->DllBase + current->SizeOfImage))) ||
|
||||||
(Name != NULL && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) ||
|
(Name && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) ||
|
||||||
(Index >= 0 && Count++ == Index))
|
(Index >= 0 && Count++ == Index))
|
||||||
{
|
{
|
||||||
wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length);
|
wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length);
|
||||||
|
@ -90,6 +88,7 @@ KdbpSymFindUserModule(IN PVOID Address OPTIONAL,
|
||||||
pInfo->RosSymInfo = current->PatchInformation;
|
pInfo->RosSymInfo = current->PatchInformation;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +102,8 @@ KdbpSymFindUserModule(IN PVOID Address OPTIONAL,
|
||||||
* \sa KdbpSymFindUserModule
|
* \sa KdbpSymFindUserModule
|
||||||
*/
|
*/
|
||||||
static BOOLEAN
|
static BOOLEAN
|
||||||
KdbpSymFindModule(IN PVOID Address OPTIONAL,
|
KdbpSymFindModule(
|
||||||
|
IN PVOID Address OPTIONAL,
|
||||||
IN LPCWSTR Name OPTIONAL,
|
IN LPCWSTR Name OPTIONAL,
|
||||||
IN INT Index OPTIONAL,
|
IN INT Index OPTIONAL,
|
||||||
OUT PKDB_MODULE_INFO pInfo)
|
OUT PKDB_MODULE_INFO pInfo)
|
||||||
|
@ -123,9 +123,9 @@ KdbpSymFindModule(IN PVOID Address OPTIONAL,
|
||||||
current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||||
|
|
||||||
Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255);
|
Length = min(current->BaseDllName.Length / sizeof(WCHAR), 255);
|
||||||
if ((Address != NULL && (Address >= (PVOID)current->DllBase &&
|
if ((Address && (Address >= (PVOID)current->DllBase &&
|
||||||
Address < (PVOID)((ULONG_PTR)current->DllBase + current->SizeOfImage))) ||
|
Address < (PVOID)((ULONG_PTR)current->DllBase + current->SizeOfImage))) ||
|
||||||
(Name != NULL && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) ||
|
(Name && _wcsnicmp(current->BaseDllName.Buffer, Name, Length) == 0) ||
|
||||||
(Index >= 0 && Count++ == Index))
|
(Index >= 0 && Count++ == Index))
|
||||||
{
|
{
|
||||||
wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length);
|
wcsncpy(pInfo->Name, current->BaseDllName.Buffer, Length);
|
||||||
|
@ -135,6 +135,7 @@ KdbpSymFindModule(IN PVOID Address OPTIONAL,
|
||||||
pInfo->RosSymInfo = current->PatchInformation;
|
pInfo->RosSymInfo = current->PatchInformation;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +155,8 @@ KdbpSymFindModule(IN PVOID Address OPTIONAL,
|
||||||
* \sa KdbpSymFindModuleByIndex
|
* \sa KdbpSymFindModuleByIndex
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbpSymFindModuleByAddress(IN PVOID Address,
|
KdbpSymFindModuleByAddress(
|
||||||
|
IN PVOID Address,
|
||||||
OUT PKDB_MODULE_INFO pInfo)
|
OUT PKDB_MODULE_INFO pInfo)
|
||||||
{
|
{
|
||||||
return KdbpSymFindModule(Address, NULL, -1, pInfo);
|
return KdbpSymFindModule(Address, NULL, -1, pInfo);
|
||||||
|
@ -173,7 +175,8 @@ KdbpSymFindModuleByAddress(IN PVOID Address,
|
||||||
* \sa KdbpSymFindModuleByIndex
|
* \sa KdbpSymFindModuleByIndex
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbpSymFindModuleByName(IN LPCWSTR Name,
|
KdbpSymFindModuleByName(
|
||||||
|
IN LPCWSTR Name,
|
||||||
OUT PKDB_MODULE_INFO pInfo)
|
OUT PKDB_MODULE_INFO pInfo)
|
||||||
{
|
{
|
||||||
return KdbpSymFindModule(NULL, Name, -1, pInfo);
|
return KdbpSymFindModule(NULL, Name, -1, pInfo);
|
||||||
|
@ -192,7 +195,8 @@ KdbpSymFindModuleByName(IN LPCWSTR Name,
|
||||||
* \sa KdbpSymFindModuleByAddress
|
* \sa KdbpSymFindModuleByAddress
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbpSymFindModuleByIndex(IN INT Index,
|
KdbpSymFindModuleByIndex(
|
||||||
|
IN INT Index,
|
||||||
OUT PKDB_MODULE_INFO pInfo)
|
OUT PKDB_MODULE_INFO pInfo)
|
||||||
{
|
{
|
||||||
return KdbpSymFindModule(NULL, NULL, Index, pInfo);
|
return KdbpSymFindModule(NULL, NULL, Index, pInfo);
|
||||||
|
@ -210,7 +214,8 @@ KdbpSymFindModuleByIndex(IN INT Index,
|
||||||
* \retval FALSE No module containing \a Address was found, nothing was printed.
|
* \retval FALSE No module containing \a Address was found, nothing was printed.
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
KdbSymPrintAddress(IN PVOID Address)
|
KdbSymPrintAddress(
|
||||||
|
IN PVOID Address)
|
||||||
{
|
{
|
||||||
KDB_MODULE_INFO Info;
|
KDB_MODULE_INFO Info;
|
||||||
ULONG_PTR RelativeAddress;
|
ULONG_PTR RelativeAddress;
|
||||||
|
@ -259,24 +264,16 @@ KdbSymPrintAddress(IN PVOID Address)
|
||||||
* \retval STATUS_UNSUCCESSFUL None of the requested information was found.
|
* \retval STATUS_UNSUCCESSFUL None of the requested information was found.
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo,
|
KdbSymGetAddressInformation(
|
||||||
|
IN PROSSYM_INFO RosSymInfo,
|
||||||
IN ULONG_PTR RelativeAddress,
|
IN ULONG_PTR RelativeAddress,
|
||||||
OUT PULONG LineNumber OPTIONAL,
|
OUT PULONG LineNumber OPTIONAL,
|
||||||
OUT PCH FileName OPTIONAL,
|
OUT PCH FileName OPTIONAL,
|
||||||
OUT PCH FunctionName OPTIONAL)
|
OUT PCH FunctionName OPTIONAL)
|
||||||
{
|
{
|
||||||
if (!KdbpSymbolsInitialized)
|
if (!KdbpSymbolsInitialized ||
|
||||||
{
|
!RosSymInfo ||
|
||||||
return STATUS_UNSUCCESSFUL;
|
!RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber, FileName, FunctionName))
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == RosSymInfo)
|
|
||||||
{
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber,
|
|
||||||
FileName, FunctionName))
|
|
||||||
{
|
{
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
@ -297,7 +294,8 @@ KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo,
|
||||||
* \sa KdbpSymAddCachedFile
|
* \sa KdbpSymAddCachedFile
|
||||||
*/
|
*/
|
||||||
static PROSSYM_INFO
|
static PROSSYM_INFO
|
||||||
KdbpSymFindCachedFile(IN PUNICODE_STRING FileName)
|
KdbpSymFindCachedFile(
|
||||||
|
IN PUNICODE_STRING FileName)
|
||||||
{
|
{
|
||||||
PIMAGE_SYMBOL_INFO_CACHE Current;
|
PIMAGE_SYMBOL_INFO_CACHE Current;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
@ -338,7 +336,8 @@ KdbpSymFindCachedFile(IN PUNICODE_STRING FileName)
|
||||||
* \sa KdbpSymRemoveCachedFile
|
* \sa KdbpSymRemoveCachedFile
|
||||||
*/
|
*/
|
||||||
static VOID
|
static VOID
|
||||||
KdbpSymAddCachedFile(IN PUNICODE_STRING FileName,
|
KdbpSymAddCachedFile(
|
||||||
|
IN PUNICODE_STRING FileName,
|
||||||
IN PROSSYM_INFO RosSymInfo)
|
IN PROSSYM_INFO RosSymInfo)
|
||||||
{
|
{
|
||||||
PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
|
PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
|
||||||
|
@ -372,7 +371,8 @@ KdbpSymAddCachedFile(IN PUNICODE_STRING FileName,
|
||||||
* \sa KdbpSymAddCachedFile
|
* \sa KdbpSymAddCachedFile
|
||||||
*/
|
*/
|
||||||
static VOID
|
static VOID
|
||||||
KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo)
|
KdbpSymRemoveCachedFile(
|
||||||
|
IN PROSSYM_INFO RosSymInfo)
|
||||||
{
|
{
|
||||||
PIMAGE_SYMBOL_INFO_CACHE Current;
|
PIMAGE_SYMBOL_INFO_CACHE Current;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
@ -395,6 +395,7 @@ KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo)
|
||||||
RosSymDelete(Current->RosSymInfo);
|
RosSymDelete(Current->RosSymInfo);
|
||||||
ExFreePool(Current);
|
ExFreePool(Current);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&SymbolFileListLock, Irql);
|
KeReleaseSpinLock(&SymbolFileListLock, Irql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +415,8 @@ KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo)
|
||||||
* \sa KdbpSymUnloadModuleSymbols
|
* \sa KdbpSymUnloadModuleSymbols
|
||||||
*/
|
*/
|
||||||
static VOID
|
static VOID
|
||||||
KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
|
KdbpSymLoadModuleSymbols(
|
||||||
|
IN PUNICODE_STRING FileName,
|
||||||
OUT PROSSYM_INFO *RosSymInfo)
|
OUT PROSSYM_INFO *RosSymInfo)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
@ -433,7 +435,7 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
|
||||||
|
|
||||||
/* Try to find cached (already loaded) symbol file */
|
/* Try to find cached (already loaded) symbol file */
|
||||||
*RosSymInfo = KdbpSymFindCachedFile(FileName);
|
*RosSymInfo = KdbpSymFindCachedFile(FileName);
|
||||||
if (*RosSymInfo != NULL)
|
if (*RosSymInfo)
|
||||||
{
|
{
|
||||||
DPRINT("Found cached symbol file %wZ\n", FileName);
|
DPRINT("Found cached symbol file %wZ\n", FileName);
|
||||||
return;
|
return;
|
||||||
|
@ -485,22 +487,22 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
|
||||||
* \sa KdbpSymLoadModuleSymbols
|
* \sa KdbpSymLoadModuleSymbols
|
||||||
*/
|
*/
|
||||||
static VOID
|
static VOID
|
||||||
KdbpSymUnloadModuleSymbols(IN PROSSYM_INFO RosSymInfo)
|
KdbpSymUnloadModuleSymbols(
|
||||||
|
IN PROSSYM_INFO RosSymInfo)
|
||||||
{
|
{
|
||||||
DPRINT("Unloading symbols\n");
|
DPRINT("Unloading symbols\n");
|
||||||
|
|
||||||
if (RosSymInfo != NULL)
|
if (RosSymInfo)
|
||||||
{
|
|
||||||
KdbpSymRemoveCachedFile(RosSymInfo);
|
KdbpSymRemoveCachedFile(RosSymInfo);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief Load symbol info for a user module.
|
/*! \brief Load symbol info for a user module.
|
||||||
*
|
*
|
||||||
* \param LdrModule Pointer to the module to load symbols for.
|
* \param LdrModule Pointer to the module to load symbols for.
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule)
|
KdbSymLoadUserModuleSymbols(
|
||||||
|
IN PLDR_DATA_TABLE_ENTRY LdrModule)
|
||||||
{
|
{
|
||||||
static WCHAR Prefix[] = L"\\??\\";
|
static WCHAR Prefix[] = L"\\??\\";
|
||||||
UNICODE_STRING KernelName;
|
UNICODE_STRING KernelName;
|
||||||
|
@ -511,13 +513,12 @@ KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule)
|
||||||
KernelName.MaximumLength = sizeof(Prefix) + LdrModule->FullDllName.Length;
|
KernelName.MaximumLength = sizeof(Prefix) + LdrModule->FullDllName.Length;
|
||||||
KernelName.Length = KernelName.MaximumLength - sizeof(WCHAR);
|
KernelName.Length = KernelName.MaximumLength - sizeof(WCHAR);
|
||||||
KernelName.Buffer = ExAllocatePoolWithTag(NonPagedPool, KernelName.MaximumLength, TAG_KDBS);
|
KernelName.Buffer = ExAllocatePoolWithTag(NonPagedPool, KernelName.MaximumLength, TAG_KDBS);
|
||||||
if (NULL == KernelName.Buffer)
|
|
||||||
{
|
if (!KernelName.Buffer)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
memcpy(KernelName.Buffer, Prefix, sizeof(Prefix) - sizeof(WCHAR));
|
memcpy(KernelName.Buffer, Prefix, sizeof(Prefix) - sizeof(WCHAR));
|
||||||
memcpy(KernelName.Buffer + sizeof(Prefix) / sizeof(WCHAR) - 1, LdrModule->FullDllName.Buffer,
|
memcpy(KernelName.Buffer + sizeof(Prefix) / sizeof(WCHAR) - 1, LdrModule->FullDllName.Buffer, LdrModule->FullDllName.Length);
|
||||||
LdrModule->FullDllName.Length);
|
|
||||||
KernelName.Buffer[KernelName.Length / sizeof(WCHAR)] = L'\0';
|
KernelName.Buffer[KernelName.Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
|
||||||
KdbpSymLoadModuleSymbols(&KernelName, (PROSSYM_INFO*)&LdrModule->PatchInformation);
|
KdbpSymLoadModuleSymbols(&KernelName, (PROSSYM_INFO*)&LdrModule->PatchInformation);
|
||||||
|
@ -530,7 +531,8 @@ KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule)
|
||||||
* \param Process Pointer to a process.
|
* \param Process Pointer to a process.
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
KdbSymFreeProcessSymbols(IN PEPROCESS Process)
|
KdbSymFreeProcessSymbols(
|
||||||
|
IN PEPROCESS Process)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PLDR_DATA_TABLE_ENTRY Current;
|
PLDR_DATA_TABLE_ENTRY Current;
|
||||||
|
@ -539,28 +541,24 @@ KdbSymFreeProcessSymbols(IN PEPROCESS Process)
|
||||||
|
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
if (CurrentProcess != Process)
|
if (CurrentProcess != Process)
|
||||||
{
|
|
||||||
KeAttachProcess(&Process->Pcb);
|
KeAttachProcess(&Process->Pcb);
|
||||||
}
|
|
||||||
Peb = Process->Peb;
|
Peb = Process->Peb;
|
||||||
ASSERT(Peb);
|
ASSERT(Peb);
|
||||||
ASSERT(Peb->Ldr);
|
ASSERT(Peb->Ldr);
|
||||||
|
|
||||||
CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink;
|
CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink;
|
||||||
while (CurrentEntry != &Peb->Ldr->InLoadOrderModuleList &&
|
while (CurrentEntry != &Peb->Ldr->InLoadOrderModuleList && CurrentEntry)
|
||||||
CurrentEntry != NULL)
|
|
||||||
{
|
{
|
||||||
Current = CONTAINING_RECORD(CurrentEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
Current = CONTAINING_RECORD(CurrentEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||||
|
|
||||||
KdbpSymUnloadModuleSymbols(Current->PatchInformation);
|
KdbpSymUnloadModuleSymbols(Current->PatchInformation);
|
||||||
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentProcess != Process)
|
if (CurrentProcess != Process)
|
||||||
{
|
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief Load symbol info for a driver.
|
/*! \brief Load symbol info for a driver.
|
||||||
*
|
*
|
||||||
|
@ -568,7 +566,8 @@ KdbSymFreeProcessSymbols(IN PEPROCESS Process)
|
||||||
* \param Module Pointer to the driver LDR_DATA_TABLE_ENTRY.
|
* \param Module Pointer to the driver LDR_DATA_TABLE_ENTRY.
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
KdbSymLoadDriverSymbols(IN PUNICODE_STRING Filename,
|
KdbSymLoadDriverSymbols(
|
||||||
|
IN PUNICODE_STRING Filename,
|
||||||
IN PLDR_DATA_TABLE_ENTRY Module)
|
IN PLDR_DATA_TABLE_ENTRY Module)
|
||||||
{
|
{
|
||||||
/* Load symbols for the image if available */
|
/* Load symbols for the image if available */
|
||||||
|
@ -584,7 +583,8 @@ KdbSymLoadDriverSymbols(IN PUNICODE_STRING Filename,
|
||||||
* \param ModuleObject Pointer to the driver LDR_DATA_TABLE_ENTRY.
|
* \param ModuleObject Pointer to the driver LDR_DATA_TABLE_ENTRY.
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject)
|
KdbSymUnloadDriverSymbols(
|
||||||
|
IN PLDR_DATA_TABLE_ENTRY ModuleObject)
|
||||||
{
|
{
|
||||||
/* Unload symbols for module if available */
|
/* Unload symbols for module if available */
|
||||||
KdbpSymUnloadModuleSymbols(ModuleObject->PatchInformation);
|
KdbpSymUnloadModuleSymbols(ModuleObject->PatchInformation);
|
||||||
|
@ -592,7 +592,9 @@ KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInfo)
|
KdbSymProcessSymbols(
|
||||||
|
IN PANSI_STRING AnsiFileName,
|
||||||
|
IN PKD_SYMBOLS_INFO SymbolInfo)
|
||||||
{
|
{
|
||||||
BOOLEAN Found = FALSE;
|
BOOLEAN Found = FALSE;
|
||||||
PLIST_ENTRY ListHead, NextEntry;
|
PLIST_ENTRY ListHead, NextEntry;
|
||||||
|
@ -635,10 +637,8 @@ KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInf
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove symbol info if it already exists */
|
/* Remove symbol info if it already exists */
|
||||||
if (LdrEntry->PatchInformation != NULL)
|
if (LdrEntry->PatchInformation)
|
||||||
{
|
|
||||||
KdbpSymRemoveCachedFile(LdrEntry->PatchInformation);
|
KdbpSymRemoveCachedFile(LdrEntry->PatchInformation);
|
||||||
}
|
|
||||||
|
|
||||||
/* Load new symbol information */
|
/* Load new symbol information */
|
||||||
if (! RosSymCreateFromMem(LdrEntry->DllBase,
|
if (! RosSymCreateFromMem(LdrEntry->DllBase,
|
||||||
|
@ -667,7 +667,9 @@ KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInf
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdbDebugPrint(PCH Message, ULONG Length)
|
KdbDebugPrint(
|
||||||
|
PCH Message,
|
||||||
|
ULONG Length)
|
||||||
{
|
{
|
||||||
/* Nothing here */
|
/* Nothing here */
|
||||||
}
|
}
|
||||||
|
@ -680,7 +682,8 @@ KdbDebugPrint(PCH Message, ULONG Length)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdbInitialize(PKD_DISPATCH_TABLE DispatchTable,
|
KdbInitialize(
|
||||||
|
PKD_DISPATCH_TABLE DispatchTable,
|
||||||
ULONG BootPhase)
|
ULONG BootPhase)
|
||||||
{
|
{
|
||||||
PCHAR p1, p2;
|
PCHAR p1, p2;
|
||||||
|
|
Loading…
Reference in a new issue