* Copyright 2008, FranΓ§ois Revol, revol@free.fr
* Distributed under the terms of the MIT License.
*/
#include <arch/debug.h>
#include <debug.h>
#include <elf.h>
#include <kernel.h>
#include <signal.h>
#include "disasm_arch.h"
int
disasm_command(int argc, char **argv)
{
int argi = 1;
uint64 backCount = 0;
if (argi < argc && strcmp(argv[argi], "-b") == 0) {
if (++argi >= argc) {
print_debugger_command_usage(argv[0]);
return 0;
}
if (!evaluate_debug_expression(argv[argi++], &backCount, false))
return 0;
}
if (argi + 2 < argc) {
print_debugger_command_usage(argv[0]);
return 0;
}
uint64 pc;
if (argi < argc) {
if (!evaluate_debug_expression(argv[argi++], &pc, false))
return 0;
} else {
pc = (addr_t)arch_debug_get_interrupt_pc(NULL);
if (pc == 0) {
kprintf("Failed to get current PC!\n");
return 0;
}
}
uint64 count = 10;
if (argi < argc) {
if (!evaluate_debug_expression(argv[argi++], &count, false))
return 0;
}
addr_t baseAddress = 0;
if (backCount > 0) {
status_t error;
const char *symbol;
const char *imageName;
bool exactMatch;
if (IS_KERNEL_ADDRESS(pc)) {
error = elf_debug_lookup_symbol_address(pc, &baseAddress, &symbol,
&imageName, &exactMatch);
} else {
error = elf_debug_lookup_user_symbol_address(
debug_get_debugged_thread()->team, pc, &baseAddress, &symbol,
&imageName, &exactMatch);
}
if (error != B_OK) {
baseAddress = 0;
backCount = 0;
}
}
disasm_arch_dump_insns((addr_t)pc, count, baseAddress, backCount);
return 0;
}
static status_t
std_ops(int32 op, ...)
{
if (op == B_MODULE_INIT) {
status_t err = disasm_arch_init();
if (err != B_OK)
return err;
err = add_debugger_command_etc("dis", disasm_command,
"Print disassembly at address",
"[ -b <back count> ] [ <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"
" starting at <address>.\n"
" -b <back count> - Number of instruction to disassemble before\n"
" <address>.\n", 0);
if (err != B_OK)
disasm_arch_fini();
return err;
} else if (op == B_MODULE_UNINIT) {
remove_debugger_command("dis", disasm_command);
return disasm_arch_fini();
}
return B_BAD_VALUE;
}
static struct debugger_module_info sModuleInfo = {
{
"debugger/disasm/v1",
B_KEEP_LOADED,
&std_ops
},
NULL,
NULL,
NULL,
NULL
};
module_info *modules[] = {
(module_info *)&sModuleInfo,
NULL
};