1 /* 2 * Copyright 2008, François Revol, revol@free.fr 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <OS.h> 7 #include <KernelExport.h> 8 9 #include "disasm_arch.h" 10 #include "udis86.h" 11 12 13 static ud_t sUDState; 14 static addr_t sCurrentReadAddress; 15 static void (*sSyntax)(ud_t *) = UD_SYN_ATT; 16 static unsigned int sVendor = UD_VENDOR_INTEL; 17 18 19 static int 20 read_next_byte(struct ud*) 21 { 22 uint8_t buffer; 23 if (user_memcpy(&buffer, (void*)sCurrentReadAddress, 1) != B_OK) { 24 kprintf("<read fault>\n"); 25 return UD_EOI; 26 } 27 28 sCurrentReadAddress++; 29 return buffer; 30 } 31 32 33 static void 34 setup_disassembler(addr_t where) 35 { 36 ud_set_input_hook(&sUDState, &read_next_byte); 37 sCurrentReadAddress = where; 38 ud_set_mode(&sUDState, 32); 39 ud_set_pc(&sUDState, (uint64_t)where); 40 ud_set_syntax(&sUDState, sSyntax); 41 ud_set_vendor(&sUDState, sVendor); 42 } 43 44 45 extern "C" void 46 disasm_arch_assert(const char *condition) 47 { 48 kprintf("assert: %s\n", condition); 49 } 50 51 52 status_t 53 disasm_arch_dump_insns(addr_t where, int count, addr_t baseAddress, 54 int backCount) 55 { 56 int skipCount = 0; 57 58 if (backCount > 0) { 59 // count the instructions from base address to start address 60 setup_disassembler(baseAddress); 61 addr_t address = baseAddress; 62 int baseCount = 0; 63 int len; 64 while (address < where && (len = ud_disassemble(&sUDState)) >= 1) { 65 address += len; 66 baseCount++; 67 } 68 69 if (address == where) { 70 if (baseCount > backCount) 71 skipCount = baseCount - backCount; 72 count += baseCount; 73 } else 74 baseAddress = where; 75 } else 76 baseAddress = where; 77 78 setup_disassembler(baseAddress); 79 80 for (int i = 0; i < count; i++) { 81 int ret; 82 ret = ud_disassemble(&sUDState); 83 if (ret < 1) 84 break; 85 86 if (skipCount > 0) { 87 skipCount--; 88 continue; 89 } 90 91 addr_t address = (addr_t)ud_insn_off(&sUDState); 92 if (address == where) 93 kprintf("\x1b[34m"); 94 95 // TODO: dig operands and lookup symbols 96 kprintf("0x%08lx: %16.16s\t%s\n", address, ud_insn_hex(&sUDState), 97 ud_insn_asm(&sUDState)); 98 99 if (address == where) 100 kprintf("\x1b[m"); 101 } 102 return B_OK; 103 } 104 105 106 status_t 107 disasm_arch_init() 108 { 109 ud_init(&sUDState); 110 // XXX: check for AMD and set sVendor; 111 return B_OK; 112 } 113 114 status_t 115 disasm_arch_fini() 116 { 117 return B_OK; 118 } 119 120 121