From cd560820779dfe7e133a4b33594ef23a53bb17e8 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 24 Aug 2008 18:16:31 +0000 Subject: [PATCH] * Register command with add_debugger_command_etc() and show some nicer usage text. * Removed "length" parameter from disasm_arch_dump_insns() and the instruction count limit. If at all this should be an architecture implementation specific limitation. * In the x86 case we use an input hook instead of a fixed buffer, now. * Addressed TODO: If no address is given, the current iframe's PC is used. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27187 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/debugger/disasm/disasm.cpp | 50 +++++++++++++------ .../kernel/debugger/disasm/disasm_arch.h | 2 +- .../debugger/disasm/m68k/disasm_arch.cpp | 2 +- .../debugger/disasm/ppc/disasm_arch.cpp | 2 +- .../debugger/disasm/x86/disasm_arch.cpp | 25 ++++++++-- 5 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/add-ons/kernel/debugger/disasm/disasm.cpp b/src/add-ons/kernel/debugger/disasm/disasm.cpp index d3f1c0f02f..7d379cdff5 100644 --- a/src/add-ons/kernel/debugger/disasm/disasm.cpp +++ b/src/add-ons/kernel/debugger/disasm/disasm.cpp @@ -3,32 +3,48 @@ * Distributed under the terms of the MIT License. */ +#include #include #include #include "disasm_arch.h" + int disasm_command(int argc, char **argv) { - uint64 pc; - size_t count = 10; - - if (argc < 2) { - kprintf("Usage: dis addr [count]\n"); - return 1; + if (argc > 3) { + print_debugger_command_usage(argv[0]); + return 0; + } + + // get PC + uint64 pc; + if (argc >= 2) { + if (!evaluate_debug_expression(argv[1], &pc, false)) + return 0; + } else { + pc = (addr_t)arch_debug_get_interrupt_pc(); + if (pc == 0) { + kprintf("Failed to get current PC!\n"); + return 0; + } + } + + // get count + uint64 count = 10; + if (argc >= 3) { + if (!evaluate_debug_expression(argv[2], &count, false)) + return 0; } - // TODO: use iframe pc by default // TODO: autoincrement - pc = parse_expression(argv[1]); - if (argc > 2) - count = (size_t)parse_expression(argv[2]); - count = MIN(count, 50); - disasm_arch_dump_insns((addr_t)pc, 200, count); + + disasm_arch_dump_insns((addr_t)pc, count); return 0; } + static status_t std_ops(int32 op, ...) { @@ -38,7 +54,13 @@ std_ops(int32 op, ...) err = disasm_arch_init(); if (err < 0) return err; - return add_debugger_command("dis", disasm_command, "output disassembly at address"); + return add_debugger_command_etc("dis", disasm_command, + "Print disassembly at address", + "[
[ ] ]\n" + "Prints disassembly at address.\n" + "
- Address at which to start disassembling\n" + " (defaults to current PC).\n" + " - Number of instructions to disassemble.\n", 0); } else if (op == B_MODULE_UNINIT) { remove_debugger_command("dis", disasm_command); return disasm_arch_fini(); @@ -61,7 +83,7 @@ static struct debugger_module_info sModuleInfo = { NULL }; -module_info *modules[] = { +module_info *modules[] = { (module_info *)&sModuleInfo, NULL }; diff --git a/src/add-ons/kernel/debugger/disasm/disasm_arch.h b/src/add-ons/kernel/debugger/disasm/disasm_arch.h index 3ca3a6260d..adee93c1d2 100644 --- a/src/add-ons/kernel/debugger/disasm/disasm_arch.h +++ b/src/add-ons/kernel/debugger/disasm/disasm_arch.h @@ -12,7 +12,7 @@ extern "C" { extern status_t disasm_arch_init(); extern status_t disasm_arch_fini(); -extern status_t disasm_arch_dump_insns(addr_t where, size_t length, int count); +extern status_t disasm_arch_dump_insns(addr_t where, int count); #ifdef __cplusplus } diff --git a/src/add-ons/kernel/debugger/disasm/m68k/disasm_arch.cpp b/src/add-ons/kernel/debugger/disasm/m68k/disasm_arch.cpp index f0c16023df..074b398806 100644 --- a/src/add-ons/kernel/debugger/disasm/m68k/disasm_arch.cpp +++ b/src/add-ons/kernel/debugger/disasm/m68k/disasm_arch.cpp @@ -8,7 +8,7 @@ #include "disasm_arch.h" status_t -disasm_arch_dump_insns(addr_t where, size_t length, int count) +disasm_arch_dump_insns(addr_t where, int count) { return ENOENT; } diff --git a/src/add-ons/kernel/debugger/disasm/ppc/disasm_arch.cpp b/src/add-ons/kernel/debugger/disasm/ppc/disasm_arch.cpp index f0c16023df..074b398806 100644 --- a/src/add-ons/kernel/debugger/disasm/ppc/disasm_arch.cpp +++ b/src/add-ons/kernel/debugger/disasm/ppc/disasm_arch.cpp @@ -8,7 +8,7 @@ #include "disasm_arch.h" status_t -disasm_arch_dump_insns(addr_t where, size_t length, int count) +disasm_arch_dump_insns(addr_t where, int count) { return ENOENT; } diff --git a/src/add-ons/kernel/debugger/disasm/x86/disasm_arch.cpp b/src/add-ons/kernel/debugger/disasm/x86/disasm_arch.cpp index 07858aa590..348a0fca25 100644 --- a/src/add-ons/kernel/debugger/disasm/x86/disasm_arch.cpp +++ b/src/add-ons/kernel/debugger/disasm/x86/disasm_arch.cpp @@ -10,9 +10,25 @@ #include "udis86.h" static ud_t sUDState; +static addr_t sCurrentReadAddress; static void (*sSyntax)(ud_t *) = UD_SYN_ATT; static unsigned int sVendor = UD_VENDOR_INTEL; + +static int +read_next_byte(struct ud*) +{ + uint8_t buffer; + if (user_memcpy(&buffer, (void*)sCurrentReadAddress, 1) != B_OK) { + kprintf("\n"); + return UD_EOI; + } + + sCurrentReadAddress++; + return buffer; +} + + extern "C" void disasm_arch_assert(const char *condition) { @@ -21,12 +37,13 @@ disasm_arch_assert(const char *condition) status_t -disasm_arch_dump_insns(addr_t where, size_t length, int count) +disasm_arch_dump_insns(addr_t where, int count) { //status_t err; int i; - - ud_set_input_buffer(&sUDState, (unsigned char *)where, length); + + ud_set_input_hook(&sUDState, &read_next_byte); + sCurrentReadAddress = where; ud_set_mode(&sUDState, 32); ud_set_pc(&sUDState, (uint64_t)where); ud_set_syntax(&sUDState, sSyntax); @@ -37,7 +54,7 @@ disasm_arch_dump_insns(addr_t where, size_t length, int count) if (ret < 1) break; // TODO: dig operands and lookup symbols - kprintf("0x%08lx: %16.16s\t%s\n", + kprintf("0x%08lx: %16.16s\t%s\n", (uint32)(/*where +*/ ud_insn_off(&sUDState)), ud_insn_hex(&sUDState), ud_insn_asm(&sUDState));