* 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:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user