* 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
This commit is contained in:
Ingo Weinhold
2008-08-24 18:16:31 +00:00
parent de5fcb8ab4
commit cd56082077
5 changed files with 60 additions and 21 deletions
+36 -14
View File
@@ -3,32 +3,48 @@
* Distributed under the terms of the MIT License.
*/
#include <arch/debug.h>
#include <debug.h>
#include <signal.h>
#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",
"[ <address> [ <count> ] ]\n"
"Prints disassembly at address.\n"
" <address> - Address at which to start disassembling\n"
" (defaults to current PC).\n"
" <count> - 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
};
@@ -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
}
@@ -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;
}
@@ -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;
}
@@ -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("<read fault>\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));