/*++ Copyright (c) 2013 Minoca Corp. All Rights Reserved Module Name: cmdtab.c Abstract: This module defines the command table for the debugger. Author: Evan Green 11-Dec-2013 Environment: Debug --*/ // // ------------------------------------------------------------------- Includes // #include "dbgrtl.h" #include #include #include #include "dbgapi.h" #include "symbols.h" #include "dbgrprof.h" #include "dbgrcomm.h" #include "extsp.h" #include #include #include #include // // ---------------------------------------------------------------- Definitions // #define DBG_DISPATCH_EXCEPTION_DESCRIPTION "Runs a debugger extension command." #define DBG_SWITCH_PROCESSOR_DESCRIPTION \ "Switch to another processor (kernel mode) or thread (user mode)." #define DBGR_QUIT_DESCRIPTION "Exits the local debugger." #define DBGR_GET_SET_REGISTERS_DESCRIPTION "Get and set registers." #define DBGR_GET_SPECIAL_REGISTERS_DESCRIPTION "Get and set special registers." #define DBGR_GO_DESCRIPTION "Continue execution (go)." #define DBGR_RETURN_TO_CALLER_DESCRIPTION \ "Continue to calling function (go up)." #define DBGR_STEP_INTO_DESCRIPTION "Step in." #define DBGR_STEP_OVER_DESCRIPTION "Step over." #define DBGR_SET_SOURCE_STEPPING_DESCRIPTION \ "Enable or disable source line level stepping." #define DBGR_SOURCE_LINE_PRINTING_DESCRIPTION \ "Enable or disable printing of file and line numbers with each address." #define DBGR_SOURCE_AT_ADDRESS_DESCRIPTION \ "Display the source file and line number for the given address." #define DBGR_DISASSEMBLE_DESCRIPTION \ "Disassemble instructions at the current or specified address." #define DBGR_PRINT_CALL_STACK_DESCRIPTION "Print the current call stack." #define DBGR_PRINT_CALL_STACK_NUMBERED_DESCRIPTION \ "Print the current call stack with frame numbers." #define DBGR_SEARCH_SYMBOLS_DESCRIPTION "Search for a symbol by name." #define DBGR_DUMP_TYPE_DESCRIPTION "Dump information about a type." #define DBGR_DUMP_LIST_DESCRIPTION "Dump a doubly-linked list." #define DBGR_EVALUATE_DESCRIPTION "Evaluate a numeric or symbolic expression." #define DBGR_PRINT_LOCALS_DESCRIPTION "Dump local variables." #define DBGR_DUMP_BYTES_DESCRIPTION "Dump bytes (8-bit) from memory." #define DBGR_DUMP_CHARACTERS_DESCRIPTION "Dump characters (8-bit) from memory." #define DBGR_DUMP_WORDS_DESCRIPTION "Dump words (16-bit) from memory." #define DBGR_DUMP_DWORDS_DESCRIPTION "Dump double words (32-bit) from memory." #define DBGR_DUMP_QWORDS_DESCRIPTION "Dump quad words (64-bit) from memory." #define DBGR_EDIT_BYTES_DESCRIPTION "Edit bytes (8-bit) in memory." #define DBGR_EDIT_WORDS_DESCRIPTION "Edit words (16-bit) in memory." #define DBGR_EDIT_DWORDS_DESCRIPTION "Edit double-words (32-bit) in memory." #define DBGR_EDIT_QWORDS_DESCRIPTION "Edit quad-words (64-bit) in memory." #define DBGR_SET_FRAME_DESCRIPTION "Set the current call stack frame." #define DBGR_LIST_BREAKPOINTS_DESCRIPTION "List all breakpoints." #define DBGR_ENABLE_BREAKPOINT_DESCRIPTION "Enable a breakpoint by number." #define DBGR_DISABLE_BREAKPOINT_DESCRIPTION "Disable a breakpoint by number." #define DBGR_CREATE_BREAK_POINT_DESCRIPTION "Create a breakpoint." #define DBGR_DELETE_BREAK_POINT_DESCRIPTION \ "Clear (delete) a breakpoint by number." #define DBGR_SET_SYMBOL_PATH_DESCRIPTION "Get or set the symbol search path." #define DBGR_APPEND_SYMBOL_PATH_DESCRIPTION \ "Append a path to the symbol search path." #define DBGR_SET_SOURCE_PATH_DESCRIPTION "Get or set the source search path." #define DBGR_APPEND_SOURCE_PATH_DESCRIPTION \ "Append a path to the source search path." #define DBGR_RELOAD_SYMBOLS_DESCRIPTION \ "Reload all symbols from the symbol search path." #define DBGR_LOAD_EXTENSION_DESCRIPTION "Load a debugger extension." #define DBGR_UNLOAD_EXTENSION_DESCRIPTION \ "Unload a debugger extension (use * to unload all)." #define DBGR_PRINT_PROCESSOR_BLOCK_DESCRIPTION \ "Dump the current processor block (kernel mode)." #define DBGR_DUMP_POINTER_SYMBOLS_DESCRIPTION \ "Dump any addresses found for memory at the given location." #define DBGR_PROFILE_DESCRIPTION \ "Profiler commands." #define DBGR_REBOOT_DESCRIPTION "Forcefully reboot the target machine." #define DBGR_HELP_DESCRIPTION "Show this help text." #define DBGR_SERVER_DESCRIPTION \ "Start a remote server so that others can connect to this session." // // ------------------------------------------------------ Data Type Definitions // // // ----------------------------------------------- Internal Function Prototypes // INT DbgrHelpCommand ( PDEBUGGER_CONTEXT Context, PSTR *Arguments, ULONG ArgumentCount ); // // -------------------------------------------------------------------- Globals // // // Define the command table, which is terminated with an entry of NULLs. The // first entry is always the extension command entry, and the second entry must // be the switch processor command. // DEBUGGER_COMMAND_ENTRY DbgrCommandTable[] = { {"!", DbgDispatchExtension, DBG_DISPATCH_EXCEPTION_DESCRIPTION}, {"~", DbgrSwitchProcessor, DBG_SWITCH_PROCESSOR_DESCRIPTION}, {"q", DbgrQuit, DBGR_QUIT_DESCRIPTION}, {"r", DbgrGetSetRegisters, DBGR_GET_SET_REGISTERS_DESCRIPTION}, {"rs", DbgrGetSetSpecialRegisters, DBGR_GET_SPECIAL_REGISTERS_DESCRIPTION}, {"g", DbgrGo, DBGR_GO_DESCRIPTION}, {"gu", DbgrReturnToCaller, DBGR_RETURN_TO_CALLER_DESCRIPTION}, {"t", DbgrStep, DBGR_STEP_INTO_DESCRIPTION}, {"p", DbgrStep, DBGR_STEP_OVER_DESCRIPTION}, {"ss", DbgrSetSourceStepping, DBGR_SET_SOURCE_STEPPING_DESCRIPTION}, {"sl", DbgrSetSourceLinePrinting, DBGR_SOURCE_LINE_PRINTING_DESCRIPTION}, {"so", DbgrShowSourceAtAddressCommand, DBGR_SOURCE_AT_ADDRESS_DESCRIPTION}, {"u", DbgrDisassemble, DBGR_DISASSEMBLE_DESCRIPTION}, {"k", DbgrPrintCallStack, DBGR_PRINT_CALL_STACK_DESCRIPTION}, {"kn", DbgrPrintCallStack, DBGR_PRINT_CALL_STACK_NUMBERED_DESCRIPTION}, {"x", DbgrSearchSymbols, DBGR_SEARCH_SYMBOLS_DESCRIPTION}, {"dt", DbgrDumpTypeCommand, DBGR_DUMP_TYPE_DESCRIPTION}, {"dl", DbgrDumpList, DBGR_DUMP_LIST_DESCRIPTION}, {"?", DbgrEvaluate, DBGR_EVALUATE_DESCRIPTION}, {"dv", DbgrPrintLocals, DBGR_PRINT_LOCALS_DESCRIPTION}, {"db", DbgrDumpMemory, DBGR_DUMP_BYTES_DESCRIPTION}, {"dc", DbgrDumpMemory, DBGR_DUMP_CHARACTERS_DESCRIPTION}, {"dw", DbgrDumpMemory, DBGR_DUMP_WORDS_DESCRIPTION}, {"dd", DbgrDumpMemory, DBGR_DUMP_DWORDS_DESCRIPTION}, {"dq", DbgrDumpMemory, DBGR_DUMP_QWORDS_DESCRIPTION}, {"eb", DbgrEditMemory, DBGR_EDIT_BYTES_DESCRIPTION}, {"ew", DbgrEditMemory, DBGR_EDIT_WORDS_DESCRIPTION}, {"ed", DbgrEditMemory, DBGR_EDIT_DWORDS_DESCRIPTION}, {"eq", DbgrEditMemory, DBGR_EDIT_QWORDS_DESCRIPTION}, {"frame", DbgrSetFrame, DBGR_SET_FRAME_DESCRIPTION}, {"bl", DbgrListBreakPoints, DBGR_LIST_BREAKPOINTS_DESCRIPTION}, {"be", DbgrEnableBreakPoint, DBGR_ENABLE_BREAKPOINT_DESCRIPTION}, {"bd", DbgrEnableBreakPoint, DBGR_DISABLE_BREAKPOINT_DESCRIPTION}, {"bp", DbgrCreateBreakPoint, DBGR_CREATE_BREAK_POINT_DESCRIPTION}, {"bc", DbgrDeleteBreakPoint, DBGR_DELETE_BREAK_POINT_DESCRIPTION}, {"sympath", DbgrSetSymbolPathCommand, DBGR_SET_SYMBOL_PATH_DESCRIPTION}, {"sympath+", DbgrSetSymbolPathCommand, DBGR_APPEND_SYMBOL_PATH_DESCRIPTION}, {"srcpath", DbgrSetSourcePathCommand, DBGR_SET_SOURCE_PATH_DESCRIPTION}, {"srcpath+", DbgrSetSourcePathCommand, DBGR_APPEND_SOURCE_PATH_DESCRIPTION}, {"reload", DbgrReloadSymbols, DBGR_RELOAD_SYMBOLS_DESCRIPTION}, {"load", DbgrLoadExtension, DBGR_LOAD_EXTENSION_DESCRIPTION}, {"unload", DbgrLoadExtension, DBGR_UNLOAD_EXTENSION_DESCRIPTION}, {"proc", DbgrPrintProcessorBlock, DBGR_PRINT_PROCESSOR_BLOCK_DESCRIPTION}, {"dps", DbgrDumpPointerSymbols, DBGR_DUMP_POINTER_SYMBOLS_DESCRIPTION}, {"profile", DbgrProfileCommand, DBGR_PROFILE_DESCRIPTION}, {"reboot", DbgrRebootCommand, DBGR_REBOOT_DESCRIPTION}, {"help", DbgrHelpCommand, DBGR_HELP_DESCRIPTION}, {"server", DbgrServerCommand, DBGR_SERVER_DESCRIPTION}, {NULL, NULL, NULL} }; // // ------------------------------------------------------------------ Functions // PDEBUGGER_COMMAND_ENTRY DbgrLookupCommand ( PSTR Command ) /*++ Routine Description: This routine attempts to find a debugger command entry. Arguments: Command - Supplies a pointer to the null-terminated string containing the name of the command that was invoked. This command is split on the period character, and the first segment is looked up. Return Value: Returns a pointer to the command entry on success. NULL if there no such command, or on failure. --*/ { PSTR CommandCopy; ULONG CommandIndex; PDEBUGGER_COMMAND_ENTRY Entry; PSTR Period; CommandCopy = NULL; Period = strchr(Command, '.'); if (Period != NULL) { CommandCopy = strdup(Command); if (CommandCopy == NULL) { return NULL; } Period = strchr(CommandCopy, '.'); *Period = '\0'; Command = CommandCopy; } // // The extension command is special as it's not delimited by a period. // if (*Command == '!') { Entry = &(DbgrCommandTable[0]); goto LookupCommandEnd; // // The switch processor command is also special as its format is ~N, where // N is a number argument. // } else if (*Command == '~') { Entry = &(DbgrCommandTable[1]); goto LookupCommandEnd; } // // Loop looking for a command that matches. Case is not important. // CommandIndex = 0; while (DbgrCommandTable[CommandIndex].Command != NULL) { Entry = &(DbgrCommandTable[CommandIndex]); if (strcasecmp(Command, Entry->Command) == 0) { goto LookupCommandEnd; } CommandIndex += 1; } Entry = NULL; LookupCommandEnd: if (CommandCopy != NULL) { free(CommandCopy); } return Entry; } // // --------------------------------------------------------- Internal Functions // INT DbgrHelpCommand ( PDEBUGGER_CONTEXT Context, PSTR *Arguments, ULONG ArgumentCount ) /*++ Routine Description: This routine prints a description of all available commands. Arguments: Context - Supplies a pointer to the application context. Arguments - Supplies an array of strings containing the arguments. The first argument is the command itself. ArgumentCount - Supplies the count of arguments. This is always at least one. Return Value: 0 on success. Returns an error code on failure. --*/ { ULONG CommandIndex; PDEBUGGER_COMMAND_ENTRY Entry; CommandIndex = 0; while (DbgrCommandTable[CommandIndex].Command != NULL) { Entry = &(DbgrCommandTable[CommandIndex]); DbgOut("%s -- %s\n", Entry->Command, Entry->HelpText); CommandIndex += 1; } return 0; }