Alex Ionescu ionucu@videotron.ca - Add KeGetCurrentPrcb function and use it where appropriate. - Fix returning of values in ExGetCurrentProcessorCpuUsage and ExGetCurrentProcessorCounts. - Move ExIsProcessorFeaturePresent from ex/init.c to ex/sysinfo.c. Modified: trunk/reactos/ntoskrnl/dbg/kdb_cli.c Modified: trunk/reactos/ntoskrnl/ex/init.c Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c Modified: trunk/reactos/ntoskrnl/include/internal/i386/ps.h Modified: trunk/reactos/ntoskrnl/ke/clock.c Modified: trunk/reactos/ntoskrnl/ke/i386/fpu.c Modified: trunk/reactos/ntoskrnl/ke/i386/irq.c Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c Modified: trunk/reactos/ntoskrnl/ke/ipi.c Modified: trunk/reactos/ntoskrnl/ps/i386/continue.c Modified: trunk/reactos/ntoskrnl/ps/idle.c Modified: trunk/reactos/ntoskrnl/ps/kill.c Modified: trunk/reactos/ntoskrnl/ps/process.c Modified: trunk/reactos/ntoskrnl/ps/w32call.c _____
Modified: trunk/reactos/ntoskrnl/dbg/kdb_cli.c --- trunk/reactos/ntoskrnl/dbg/kdb_cli.c 2005-03-12 09:21:59 UTC (rev 13964) +++ trunk/reactos/ntoskrnl/dbg/kdb_cli.c 2005-03-12 09:40:07 UTC (rev 13965) @@ -1,2320 +1,2320 @@
-/* - * ReactOS kernel - * Copyright (C) 2005 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/dbg/kdb_cli.c - * PURPOSE: Kernel debugger command line interface - * PROGRAMMER: Gregor Anich (blight@blight.eu.org) - * UPDATE HISTORY: - * Created 16/01/2005 - */ - -/* INCLUDES ******************************************************************/ - -#include <ntoskrnl.h> -#include "kdb.h" -#define NDEBUG -#include <internal/debug.h> - -/* DEFINES *******************************************************************/ - -#define KEY_BS 8 -#define KEY_ESC 27 -#define KEY_DEL 127 - -#define KEY_SCAN_UP 72 -#define KEY_SCAN_DOWN 80 - -#define KDB_ENTER_CONDITION_TO_STRING(cond) \ - ((cond) == KdbDoNotEnter ? "never" : \ - ((cond) == KdbEnterAlways ? "always" : \ - ((cond) == KdbEnterFromKmode ? "kmode" : "umode"))) - -#define KDB_ACCESS_TYPE_TO_STRING(type) \ - ((type) == KdbAccessRead ? "read" : \ - ((type) == KdbAccessWrite ? "write" : \ - ((type) == KdbAccessReadWrite ? "rdwr" : "exec"))) - -#define NPX_STATE_TO_STRING(state) \ - ((state) == NPX_STATE_INVALID ? "Invalid" : \ - ((state) == NPX_STATE_VALID ? "Valid" : \ - ((state) == NPX_STATE_DIRTY ? "Dirty" : "Unknown"))) - -/* PROTOTYPES ****************************************************************/ - -STATIC BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]); - -STATIC BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]); - -STATIC BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]); - -STATIC BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]); - -STATIC BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]); -STATIC BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]); - -/* GLOBALS *******************************************************************/ - -STATIC BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */ - -STATIC CHAR KdbCommandHistoryBuffer[2048]; /* Command history string ringbuffer */ -STATIC PCHAR KdbCommandHistory[sizeof(KdbCommandHistoryBuffer) / 8] = { NULL }; /* Command history ringbuffer */ -STATIC LONG KdbCommandHistoryBufferIndex = 0; -STATIC LONG KdbCommandHistoryIndex = 0; - -STATIC ULONG KdbNumberOfRowsPrinted = 0; -STATIC ULONG KdbNumberOfColsPrinted = 0; -STATIC BOOLEAN KdbOutputAborted = FALSE; -STATIC LONG KdbNumberOfRowsTerminal = -1; -STATIC LONG KdbNumberOfColsTerminal = -1; - -PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */ - -STATIC CONST struct -{ - PCHAR Name; - PCHAR Syntax; - PCHAR Help; - BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]); -} KdbDebuggerCommands[] = { - /* Data */ - { NULL, NULL, "Data", NULL }, - { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression }, - { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX }, - { "x", "x [address] [L count]", "Display count dwords, starting at addr.", KdbpCmdDisassembleX }, - { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs }, - { "cregs", "cregs", "Display control registers.", KdbpCmdRegs }, - { "sregs", "sregs", "Display status registers.", KdbpCmdRegs }, - { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs }, - { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame addr", KdbpCmdBackTrace }, - - /* Flow control */ - { NULL, NULL, "Flow control", NULL }, - { "cont", "cont", "Continue execution (leave debugger)", KdbpCmdContinue }, - { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep }, - { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep }, - { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList }, - { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint }, - { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint }, - { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint }, - { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint }, - { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint }, - - /* Process/Thread */ - { NULL, NULL, "Process/Thread", NULL }, - { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread }, - { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc }, - - /* System information */ - { NULL, NULL, "System info", NULL }, - { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod }, - { "gdt", "gdt", "Display global descriptor table.", KdbpCmdGdtLdtIdt }, - { "ldt", "ldt", "Display local descriptor table.", KdbpCmdGdtLdtIdt }, - { "idt", "idt", "Display interrupt descriptor table.", KdbpCmdGdtLdtIdt }, - { "pcr", "pcr", "Display processor control region.", KdbpCmdPcr }, - { "tss", "tss", "Display task state segment.", KdbpCmdTss }, - - /* Others */ - { NULL, NULL, "Others", NULL }, - { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck }, - { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet }, - { "help", "help", "Display help screen.", KdbpCmdHelp } -}; - -/* FUNCTIONS *****************************************************************/ - -/*!\brief Evaluates an expression... - * - * Much like KdbpRpnEvaluateExpression, but prints the error message (if any) - * at the given offset. - * - * \param Expression Expression to evaluate. - * \param ErrOffset Offset (in characters) to print the error message at. - * \param Result Receives the result on success. - * - * \retval TRUE Success. - * \retval FALSE Failure. - */ -STATIC BOOLEAN -KdbpEvaluateExpression( - IN PCHAR Expression, - IN LONG ErrOffset, - OUT PULONGLONG Result) -{ - STATIC CHAR ErrMsgBuffer[130] = "^ "; - LONG ExpressionErrOffset = -1; - PCHAR ErrMsg = ErrMsgBuffer; - BOOLEAN Ok; - - Ok = KdbpRpnEvaluateExpression(Expression, KdbCurrentTrapFrame, Result, - &ExpressionErrOffset, ErrMsgBuffer + 2); - if (!Ok) - { - if (ExpressionErrOffset >= 0) - ExpressionErrOffset += ErrOffset; - else - ErrMsg += 2; - KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg); - } - - return Ok; -} - -/*!\brief Evaluates an expression and displays the result. - */ -STATIC BOOLEAN -KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]) -{ - INT i, len; - ULONGLONG Result = 0; - ULONG ul; - LONG l = 0; - BOOLEAN Ok; - - if (Argc < 2) - { - KdbpPrint("?: Argument required\n"); - return TRUE; - } - - /* Put the arguments back together */ - Argc--; - for (i = 1; i < Argc; i++) - { - len = strlen(Argv[i]); - Argv[i][len] = ' '; - } - - /* Evaluate the expression */ - Ok = KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result); - if (Ok) - { - if (Result > 0x00000000ffffffffLL) - { - if (Result & 0x8000000000000000LL) - KdbpPrint("0x%016I64x %20I64u %20I64d\n", Result, Result, Result); - else - KdbpPrint("0x%016I64x %20I64u\n", Result, Result); - } - else - { - ul = (ULONG)Result; - if (ul <= 0xff && ul >= 0x80) - l = (LONG)((CHAR)ul); - else if (ul <= 0xffff && ul >= 0x8000) - l = (LONG)((SHORT)ul); - else - l = (LONG)ul; - if (l < 0) - KdbpPrint("0x%08lx %10lu %10ld\n", ul, ul, l); - else - KdbpPrint("0x%08lx %10lu\n", ul, ul); - } - } - - return TRUE; -} - -/*!\brief Disassembles 10 instructions at eip or given address or - * displays 16 dwords from memory at given address. - */ -STATIC BOOLEAN -KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]) -{ - ULONG Count; - ULONG ul; - INT i; - ULONGLONG Result = 0; - ULONG_PTR Address = KdbCurrentTrapFrame->Tf.Eip; - LONG InstLen; - - if (Argv[0][0] == 'x') /* display memory */ - Count = 16; - else /* disassemble */ - Count = 10; - - if (Argc >= 2) - { - /* Check for [L count] part */ - ul = 0; - if (strcmp(Argv[Argc-2], "L") == 0) - { - ul = strtoul(Argv[Argc-1], NULL, 0); - if (ul > 0) - { - Count = ul; - Argc -= 2; - } - } - else if (Argv[Argc-1][0] == 'L') - { - ul = strtoul(Argv[Argc-1] + 1, NULL, 0); - if (ul > 0) - { - Count = ul; - Argc--; - } - } - - /* Put the remaining arguments back together */ - Argc--; - for (ul = 1; ul < Argc; ul++) - { - Argv[ul][strlen(Argv[ul])] = ' '; - } - Argc++; - } - - /* Evaluate the expression */ - if (Argc > 1) - { - if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result)) - return TRUE; - if (Result > (ULONGLONG)(~((ULONG_PTR)0))) - KdbpPrint("Warning: Address %I64x is beeing truncated\n"); - Address = (ULONG_PTR)Result; - } - else if (Argv[0][0] == 'x') - { - KdbpPrint("x: Address argument required.\n"); - return TRUE; - } - - if (Argv[0][0] == 'x') - { - /* Display dwords */ - ul = 0; - while (Count > 0) - { - if (!KdbSymPrintAddress((PVOID)Address)) - KdbpPrint("<%x>:", Address); - else - KdbpPrint(":"); - i = min(4, Count); - Count -= i; - while (--i >= 0) - { - if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul)))) - KdbpPrint(" ????????"); - else - KdbpPrint(" %08x", ul); - Address += sizeof(ul); - } - KdbpPrint("\n"); - } - } - else - { - /* Disassemble */ - while (Count-- > 0) - { - if (!KdbSymPrintAddress((PVOID)Address)) - KdbpPrint("<%08x>: ", Address); - else - KdbpPrint(": "); - InstLen = KdbpDisassemble(Address, KdbUseIntelSyntax); - if (InstLen < 0) - { - KdbpPrint("<INVALID>\n"); - return TRUE; - } - KdbpPrint("\n"); - Address += InstLen; - } - } - - return TRUE; -} - -/*!\brief Displays CPU registers. - */ -STATIC BOOLEAN -KdbpCmdRegs(ULONG Argc, PCHAR Argv[]) -{ - PKTRAP_FRAME Tf = &KdbCurrentTrapFrame->Tf; - INT i; - STATIC CONST PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5", - " ZF", " SF", " TF", " IF", " DF", " OF", - NULL, NULL, " NT", " BIT15", " RF", " VF", - " AC", " VIF", " VIP", " ID", " BIT22", - " BIT23", " BIT24", " BIT25", " BIT26", - " BIT27", " BIT28", " BIT29", " BIT30", - " BIT31" }; - - if (Argv[0][0] == 'r') /* regs */ - { - KdbpPrint("CS:EIP 0x%04x:0x%08x\n" - "SS:ESP 0x%04x:0x%08x\n" - " EAX 0x%08x EBX 0x%08x\n" - " ECX 0x%08x EDX 0x%08x\n" - " ESI 0x%08x EDI 0x%08x\n" - " EBP 0x%08x\n", - Tf->Cs & 0xFFFF, Tf->Eip, - Tf->Ss, Tf->Esp, - Tf->Eax, Tf->Ebx, - Tf->Ecx, Tf->Edx, - Tf->Esi, Tf->Edi, - Tf->Ebp); - KdbpPrint("EFLAGS 0x%08x ", Tf->Eflags); - for (i = 0; i < 32; i++) - { - if (i == 1) - { - if ((Tf->Eflags & (1 << 1)) == 0) - KdbpPrint(" !BIT1"); - } - else if (i == 12) - { - KdbpPrint(" IOPL%d", (Tf->Eflags >> 12) & 3); - } - else if (i == 13) - { - } - else if ((Tf->Eflags & (1 << i)) != 0) - KdbpPrint(EflagsBits[i]); - } - KdbpPrint("\n"); - } - else if (Argv[0][0] == 'c') /* cregs */ - { - ULONG Cr0, Cr2, Cr3, Cr4; - struct __attribute__((packed)) { - USHORT Limit; - ULONG Base; - } Gdtr, Ldtr, Idtr; - ULONG Tr; - STATIC CONST PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" }; - STATIC CONST PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE", - " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - - Cr0 = KdbCurrentTrapFrame->Cr0; - Cr2 = KdbCurrentTrapFrame->Cr2; - Cr3 = KdbCurrentTrapFrame->Cr3; - Cr4 = KdbCurrentTrapFrame->Cr4; - - /* Get descriptor table regs */ - asm volatile("sgdt %0" : : "m"(Gdtr)); - asm volatile("sldt %0" : : "m"(Ldtr)); - asm volatile("sidt %0" : : "m"(Idtr)); - - /* Get the task register */ - asm volatile("str %0" : "=g"(Tr)); - - /* Display the control registers */ - KdbpPrint("CR0 0x%08x ", Cr0); - for (i = 0; i < 32; i++) - { - if (Cr0Bits[i] == NULL) - continue; - if ((Cr0 & (1 << i)) != 0) - KdbpPrint(Cr0Bits[i]); - } - KdbpPrint("\nCR2 0x%08x\n", Cr2); - KdbpPrint("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000), - (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" ); - KdbpPrint("CR4 0x%08x ", Cr4); - for (i = 0; i < 32; i++) - { - if (Cr4Bits[i] == NULL) - continue; - if ((Cr4 & (1 << i)) != 0) - KdbpPrint(Cr4Bits[i]); - } - - /* Display the descriptor table regs */ - KdbpPrint("\nGDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit); - KdbpPrint("LDTR Base 0x%08x Size 0x%04x\n", Ldtr.Base, Ldtr.Limit); - KdbpPrint("IDTR Base 0x%08x Size 0x%04x\n", Idtr.Base, Idtr.Limit); - } - else if (Argv[0][0] == 's') /* sregs */ - { - KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n", - Tf->Cs & 0xffff, (Tf->Cs & 0xffff) >> 3, - (Tf->Cs & (1 << 2)) ? 'L' : 'G', Tf->Cs & 3); - KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n", - Tf->Ds, Tf->Ds >> 3, (Tf->Ds & (1 << 2)) ? 'L' : 'G', Tf->Ds & 3); - KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n", - Tf->Es, Tf->Es >> 3, (Tf->Es & (1 << 2)) ? 'L' : 'G', Tf->Es & 3); - KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n", - Tf->Fs, Tf->Fs >> 3, (Tf->Fs & (1 << 2)) ? 'L' : 'G', Tf->Fs & 3); - KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n", - Tf->Gs, Tf->Gs >> 3, (Tf->Gs & (1 << 2)) ? 'L' : 'G', Tf->Gs & 3); - KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n", - Tf->Ss, Tf->Ss >> 3, (Tf->Ss & (1 << 2)) ? 'L' : 'G', Tf->Ss & 3); - } - else /* dregs */ - { - ASSERT(Argv[0][0] == 'd'); - KdbpPrint("DR0 0x%08x\n" - "DR1 0x%08x\n" - "DR2 0x%08x\n" - "DR3 0x%08x\n" - "DR6 0x%08x\n" - "DR7 0x%08x\n", - Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3, - Tf->Dr6, Tf->Dr7); - } - return TRUE; -} - -/*!\brief Displays a backtrace. - */ -STATIC BOOLEAN -KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]) -{ - ULONG Count; - ULONG ul; - ULONGLONG Result = 0; - ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp; - ULONG_PTR Address; - - if (Argc >= 2) - { - /* Check for [L count] part */ - ul = 0; - if (strcmp(Argv[Argc-2], "L") == 0) - { - ul = strtoul(Argv[Argc-1], NULL, 0); - if (ul > 0) - { - Count = ul; - Argc -= 2; - } - } - else if (Argv[Argc-1][0] == 'L') - { - ul = strtoul(Argv[Argc-1] + 1, NULL, 0); - if (ul > 0) - { - Count = ul; - Argc--; - } - } - - /* Put the remaining arguments back together */ - Argc--; - for (ul = 1; ul < Argc; ul++) - { - Argv[ul][strlen(Argv[ul])] = ' '; - } - Argc++; - } - - /* Check if frame addr or thread id is given. */ - if (Argc > 1) - { - if (Argv[1][0] == '*') - { - Argv[1]++; - /* Evaluate the expression */ - if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result)) - return TRUE; - if (Result > (ULONGLONG)(~((ULONG_PTR)0))) - KdbpPrint("Warning: Address %I64x is beeing truncated\n"); - Frame = (ULONG_PTR)Result; - } - else - { - - KdbpPrint("Thread backtrace not supported yet!\n"); - return TRUE; - } - } - - KdbpPrint("Frames:\n"); - while (Frame != 0) - { - if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof (ULONG_PTR)))) - { - KdbpPrint("Couldn't access memory at 0x%x!\n", Frame + sizeof(ULONG_PTR)); - break; - } - if (!KdbSymPrintAddress((PVOID)Address)) - KdbpPrint("<%08x>\n", Address); - else - KdbpPrint("\n"); - if (!NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof (ULONG_PTR)))) - { - KdbpPrint("Couldn't access memory at 0x%x!\n", Frame); - break; - } - } - - return TRUE; -} - -/*!\brief Continues execution of the system/leaves KDB. - */ -STATIC BOOLEAN -KdbpCmdContinue(ULONG Argc, PCHAR Argv[]) -{ - /* Exit the main loop */ - return FALSE; -} - -/*!\brief Continues execution of the system/leaves KDB. - */ -STATIC BOOLEAN -KdbpCmdStep(ULONG Argc, PCHAR Argv[]) -{ - ULONG Count = 1; - - if (Argc > 1) - { - Count = strtoul(Argv[1], NULL, 0); - if (Count == 0) - { - KdbpPrint("%s: Integer argument required\n", Argv[0]); - return TRUE; - } - } - - if (Argv[0][0] == 'n') - KdbSingleStepOver = TRUE; - else - KdbSingleStepOver = FALSE; - - /* Set the number of single steps and return to the interrupted code. */ - KdbNumSingleSteps = Count; - - return FALSE; -} - -/*!\brief Lists breakpoints. - */ -STATIC BOOLEAN -KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[]) -{ - LONG l; - ULONG_PTR Address = 0; - KDB_BREAKPOINT_TYPE Type = 0; - KDB_ACCESS_TYPE AccessType = 0; - UCHAR Size = 0; - UCHAR DebugReg = 0; - BOOLEAN Enabled = FALSE; - BOOLEAN Global = FALSE; - PEPROCESS Process = NULL; - PCHAR str1, str2, ConditionExpr, GlobalOrLocal; - CHAR Buffer[20]; - - l = KdbpGetNextBreakPointNr(0); - if (l < 0) - { - KdbpPrint("No breakpoints.\n"); - return TRUE; - } - - KdbpPrint("Breakpoints:\n"); - do - { - if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg, - &Enabled, &Global, &Process, &ConditionExpr)) - { - continue; - } - - if (l == KdbLastBreakPointNr) - { - str1 = "\x1b[1m*"; - str2 = "\x1b[0m"; - } - else - { - str1 = " "; - str2 = ""; - } - - if (Global) - GlobalOrLocal = " global"; - else - { - GlobalOrLocal = Buffer; - sprintf(Buffer, " PID 0x%08lx", - (ULONG)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE)); - } - - if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary) - { - KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n", - str1, l, Address, - Enabled ? "" : " disabled", - GlobalOrLocal, - ConditionExpr ? " IF " : "", - ConditionExpr ? ConditionExpr : "", - str2); - } - else if (Type == KdbBreakPointHardware) - { - if (!Enabled) - { - KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address, - KDB_ACCESS_TYPE_TO_STRING(AccessType), - Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"), - GlobalOrLocal, - ConditionExpr ? " IF " : "", - ConditionExpr ? ConditionExpr : "", - str2); - } - else - { - KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address, - KDB_ACCESS_TYPE_TO_STRING(AccessType), - Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"), - DebugReg, - GlobalOrLocal, - ConditionExpr ? " IF " : "", - ConditionExpr ? ConditionExpr : "", - str2); - } - } - } - while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0); - - return TRUE; -} - -/*!\brief Enables, disables or clears a breakpoint. - */ -STATIC BOOLEAN -KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[]) -{ - PCHAR pend; - ULONG BreakPointNr; - - if (Argc < 2) - { - KdbpPrint("%s: argument required\n", Argv[0]); - return TRUE; - } - - pend = Argv[1]; - BreakPointNr = strtoul(Argv[1], &pend, 0); - if (pend == Argv[1] || *pend != '\0') - { - KdbpPrint("%s: integer argument required\n", Argv[0]); - return TRUE; - } - - if (Argv[0][1] == 'e') /* enable */ - { - KdbpEnableBreakPoint(BreakPointNr, NULL); - } - else if (Argv [0][1] == 'd') /* disable */ - { - KdbpDisableBreakPoint(BreakPointNr, NULL); - } - else /* clear */ - { - ASSERT(Argv[0][1] == 'c'); - KdbpDeleteBreakPoint(BreakPointNr, NULL); - } - - return TRUE; -} - -/*!\brief Sets a software or hardware (memory) breakpoint at the given address. - */ -STATIC BOOLEAN -KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]) -{ - ULONGLONG Result = 0; - ULONG_PTR Address; - KDB_BREAKPOINT_TYPE Type; - UCHAR Size = 0; - KDB_ACCESS_TYPE AccessType = 0; - INT AddressArgIndex, ConditionArgIndex, i; - BOOLEAN Global = TRUE; - - if (Argv[0][2] == 'x') /* software breakpoint */ - { - if (Argc < 2) - { - KdbpPrint("bpx: Address argument required.\n"); - return TRUE; - } - - AddressArgIndex = 1; - Type = KdbBreakPointSoftware; - } - else /* memory breakpoint */ - { - ASSERT(Argv[0][2] == 'm'); - - if (Argc < 2) - { - KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n"); - return TRUE; - } - - if (_stricmp(Argv[1], "x") == 0) - AccessType = KdbAccessExec; - else if (_stricmp(Argv[1], "r") == 0) - AccessType = KdbAccessRead; - else if (_stricmp(Argv[1], "w") == 0) - AccessType = KdbAccessWrite; - else if (_stricmp(Argv[1], "rw") == 0) - AccessType = KdbAccessReadWrite; - else - { - KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]); - return TRUE; - } - - if (Argc < 3) - { - KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size"); - return TRUE; - } - AddressArgIndex = 3; - if (_stricmp(Argv[2], "byte") == 0) - Size = 1; - else if (_stricmp(Argv[2], "word") == 0) - Size = 2; - else if (_stricmp(Argv[2], "dword") == 0) - Size = 4; - else if (AccessType == KdbAccessExec) - { - Size = 1; - AddressArgIndex--; - } - else - { - KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]); - return TRUE; - } - - if (Argc <= AddressArgIndex) - { - KdbpPrint("bpm: Address argument required.\n"); - return TRUE; - } - - Type = KdbBreakPointHardware; - } - - /* Put the arguments back together */ - ConditionArgIndex = -1; - for (i = AddressArgIndex; i < (Argc-1); i++) - { - if (strcmp(Argv[i+1], "IF") == 0) /* IF found */ - { - ConditionArgIndex = i + 2; - if (ConditionArgIndex >= Argc) - { - KdbpPrint("%s: IF requires condition expression.\n", Argv[0]); - return TRUE; - } - for (i = ConditionArgIndex; i < (Argc-1); i++) - Argv[i][strlen(Argv[i])] = ' '; - break; - } - Argv[i][strlen(Argv[i])] = ' '; - } - - /* Evaluate the address expression */ - if (!KdbpEvaluateExpression(Argv[AddressArgIndex], - sizeof("kdb:> ")-1 + (Argv[AddressArgIndex]-Argv[0]), - &Result)) - { - return TRUE; - } - if (Result > (ULONGLONG)(~((ULONG_PTR)0))) - KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]); - Address = (ULONG_PTR)Result; - - KdbpInsertBreakPoint(Address, Type, Size, AccessType, - (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex], - Global, NULL); - - return TRUE; -} - -/*!\brief Lists threads or switches to another thread context. - */ -STATIC BOOLEAN -KdbpCmdThread(ULONG Argc, PCHAR Argv[]) -{ - PLIST_ENTRY Entry; - PETHREAD Thread = NULL; - PEPROCESS Process = NULL; - PULONG Esp; - PULONG Ebp; - ULONG Eip; - ULONG ul = 0; - PCHAR State, pend, str1, str2; - STATIC CONST PCHAR ThreadStateToString[THREAD_STATE_MAX] = - { "Initialized", "Ready", "Running", - "Suspended", "Frozen", "Terminated1", - "Terminated2", "Blocked" }; - ASSERT(KdbCurrentProcess != NULL); - - if (Argc >= 2 && _stricmp(Argv[1], "list") == 0) - { - Process = KdbCurrentProcess; - - if (Argc >= 3) - { - ul = strtoul(Argv[2], &pend, 0); - if (Argv[2] == pend) - { - KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]); - return TRUE; - } - if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process))) - { - KdbpPrint("thread: Invalid process id!\n"); - return TRUE; - } - } - - Entry = Process->ThreadListHead.Flink; - if (Entry == &Process->ThreadListHead) - { - if (Argc >= 3) - KdbpPrint("No threads in process 0x%08x!\n", ul); - else - KdbpPrint("No threads in current process!\n"); - return TRUE; - } - - KdbpPrint(" TID State Prior. Affinity EBP EIP\n"); - do - { - Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry); - - if (Thread == KdbCurrentThread) - { - str1 = "\x1b[1m*"; - str2 = "\x1b[0m"; - } - else - { - str1 = " "; - str2 = ""; - } - - if (Thread->Tcb.TrapFrame != NULL) - { - Esp = (PULONG)Thread->Tcb.TrapFrame->Esp; - Ebp = (PULONG)Thread->Tcb.TrapFrame->Ebp; - Eip = Thread->Tcb.TrapFrame->Eip; - } - else - { - Esp = (PULONG)Thread->Tcb.KernelStack; - Ebp = (PULONG)Esp[4]; - Eip = 0; - if (Ebp != NULL) /* FIXME: Should we attach to the process to read Ebp[1]? */ - KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof (Eip));; - } - if (Thread->Tcb.State < THREAD_STATE_MAX) - State = ThreadStateToString[Thread->Tcb.State]; - else - State = "Unknown"; - - KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n", - str1, - Thread->Cid.UniqueThread, - State, - Thread->Tcb.Priority, - Thread->Tcb.Affinity, - Ebp, - Eip, - str2); - - Entry = Entry->Flink; - } - while (Entry != &Process->ThreadListHead); - } - else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0) - { - if (Argc < 3) - { - KdbpPrint("thread attach: thread id argument required!\n"); - return TRUE; - } - - ul = strtoul(Argv[2], &pend, 0); - if (Argv[2] == pend) - { - KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]); - return TRUE; - } - if (!KdbpAttachToThread((PVOID)ul)) - { - return TRUE; - } - KdbpPrint("Attached to thread 0x%08x.\n", ul); - } - else - { - Thread = KdbCurrentThread; - - if (Argc >= 2) - { - ul = strtoul(Argv[1], &pend, 0); - if (Argv[1] == pend) - { - KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]); - return TRUE; - } - if (!NT_SUCCESS(PsLookupThreadByThreadId((PVOID)ul, &Thread))) [truncated at 1000 lines; 4259 more skipped]