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));