1 /* 2 * Copyright 2008, François Revol, revol@free.fr 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <arch/debug.h> 7 #include <debug.h> 8 #include <elf.h> 9 #include <kernel.h> 10 #include <signal.h> 11 12 #include "disasm_arch.h" 13 14 15 int 16 disasm_command(int argc, char **argv) 17 { 18 int argi = 1; 19 20 // get back count 21 uint64 backCount = 0; 22 if (argi < argc && strcmp(argv[argi], "-b") == 0) { 23 if (++argi >= argc) { 24 print_debugger_command_usage(argv[0]); 25 return 0; 26 } 27 28 if (!evaluate_debug_expression(argv[argi++], &backCount, false)) 29 return 0; 30 } 31 32 if (argi + 2 < argc) { 33 print_debugger_command_usage(argv[0]); 34 return 0; 35 } 36 37 // get PC 38 uint64 pc; 39 if (argi < argc) { 40 if (!evaluate_debug_expression(argv[argi++], &pc, false)) 41 return 0; 42 } else { 43 pc = (addr_t)arch_debug_get_interrupt_pc(NULL); 44 if (pc == 0) { 45 kprintf("Failed to get current PC!\n"); 46 return 0; 47 } 48 } 49 50 // get count 51 uint64 count = 10; 52 if (argi < argc) { 53 if (!evaluate_debug_expression(argv[argi++], &count, false)) 54 return 0; 55 } 56 57 // TODO: autoincrement 58 59 // if back count is given, compute base address 60 addr_t baseAddress = 0; 61 if (backCount > 0) { 62 status_t error; 63 const char *symbol; 64 const char *imageName; 65 bool exactMatch; 66 67 if (IS_KERNEL_ADDRESS(pc)) { 68 error = elf_debug_lookup_symbol_address(pc, &baseAddress, &symbol, 69 &imageName, &exactMatch); 70 } else { 71 error = elf_debug_lookup_user_symbol_address( 72 debug_get_debugged_thread()->team, pc, &baseAddress, &symbol, 73 &imageName, &exactMatch); 74 } 75 76 if (error != B_OK) { 77 baseAddress = 0; 78 backCount = 0; 79 } 80 } 81 82 disasm_arch_dump_insns((addr_t)pc, count, baseAddress, backCount); 83 return 0; 84 } 85 86 87 static status_t 88 std_ops(int32 op, ...) 89 { 90 if (op == B_MODULE_INIT) { 91 status_t err = disasm_arch_init(); 92 if (err != B_OK) 93 return err; 94 95 err = add_debugger_command_etc("dis", disasm_command, 96 "Print disassembly at address", 97 "[ -b <back count> ] [ <address> [ <count> ] ]\n" 98 "Prints disassembly at address.\n" 99 " <address> - Address at which to start disassembling\n" 100 " (defaults to current PC).\n" 101 " <count> - Number of instructions to disassemble\n" 102 " starting at <address>.\n" 103 " -b <back count> - Number of instruction to disassemble before\n" 104 " <address>.\n", 0); 105 if (err != B_OK) 106 disasm_arch_fini(); 107 return err; 108 } else if (op == B_MODULE_UNINIT) { 109 remove_debugger_command("dis", disasm_command); 110 return disasm_arch_fini(); 111 } 112 113 return B_BAD_VALUE; 114 } 115 116 117 static struct debugger_module_info sModuleInfo = { 118 { 119 "debugger/disasm/v1", 120 B_KEEP_LOADED, 121 &std_ops 122 }, 123 124 NULL, 125 NULL, 126 NULL, 127 NULL 128 }; 129 130 module_info *modules[] = { 131 (module_info *)&sModuleInfo, 132 NULL 133 }; 134