vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / debugger / disasm / x86 / disasm_arch.cpp
bloba5b027343dbf4737596aea917d8b3cb78b9d67eb
1 /*
2 * Copyright 2008, François Revol, revol@free.fr
3 * Distributed under the terms of the MIT License.
4 */
6 #include <OS.h>
7 #include <KernelExport.h>
9 #include <debug.h>
11 #include "disasm_arch.h"
12 #include "elf.h"
13 #include "udis86.h"
16 static ud_t sUDState;
17 static addr_t sCurrentReadAddress;
18 static void (*sSyntax)(ud_t *) = UD_SYN_ATT;
19 static unsigned int sVendor = UD_VENDOR_INTEL;
22 static int
23 read_next_byte(struct ud*)
25 uint8_t buffer;
26 if (debug_memcpy(B_CURRENT_TEAM, &buffer, (void*)sCurrentReadAddress, 1)
27 != B_OK) {
28 kprintf("<read fault>\n");
29 return UD_EOI;
32 sCurrentReadAddress++;
33 return buffer;
37 static const char*
38 resolve_symbol(struct ud*, uint64_t address, int64_t* offset)
40 const char* symbolName;
41 addr_t baseAddress;
42 status_t error;
44 if (IS_KERNEL_ADDRESS(address)) {
45 error = elf_debug_lookup_symbol_address(address, &baseAddress,
46 &symbolName, NULL, NULL);
47 } else {
48 error = elf_debug_lookup_user_symbol_address(
49 debug_get_debugged_thread()->team, address, &baseAddress,
50 &symbolName, NULL, NULL);
53 if (error != B_OK)
54 return NULL;
56 *offset = address - baseAddress;
57 return symbolName;
61 static void
62 setup_disassembler(addr_t where)
64 ud_set_input_hook(&sUDState, &read_next_byte);
65 sCurrentReadAddress = where;
66 ud_set_mode(&sUDState, 32);
67 ud_set_pc(&sUDState, (uint64_t)where);
68 ud_set_syntax(&sUDState, sSyntax);
69 ud_set_vendor(&sUDState, sVendor);
70 ud_set_sym_resolver(&sUDState, resolve_symbol);
74 extern "C" void
75 disasm_arch_assert(const char *condition)
77 kprintf("assert: %s\n", condition);
81 status_t
82 disasm_arch_dump_insns(addr_t where, int count, addr_t baseAddress,
83 int backCount)
85 int skipCount = 0;
87 if (backCount > 0) {
88 // count the instructions from base address to start address
89 setup_disassembler(baseAddress);
90 addr_t address = baseAddress;
91 int baseCount = 0;
92 int len;
93 while (address < where && (len = ud_disassemble(&sUDState)) >= 1) {
94 address += len;
95 baseCount++;
98 if (address == where) {
99 if (baseCount > backCount)
100 skipCount = baseCount - backCount;
101 count += baseCount;
102 } else
103 baseAddress = where;
104 } else
105 baseAddress = where;
107 setup_disassembler(baseAddress);
109 for (int i = 0; i < count; i++) {
110 int ret;
111 ret = ud_disassemble(&sUDState);
112 if (ret < 1)
113 break;
115 if (skipCount > 0) {
116 skipCount--;
117 continue;
120 addr_t address = (addr_t)ud_insn_off(&sUDState);
121 if (address == where)
122 kprintf("\x1b[34m");
124 // TODO: dig operands and lookup symbols
125 kprintf("0x%08lx: %16.16s\t%s\n", address, ud_insn_hex(&sUDState),
126 ud_insn_asm(&sUDState));
128 if (address == where)
129 kprintf("\x1b[m");
131 return B_OK;
135 status_t
136 disasm_arch_init()
138 ud_init(&sUDState);
139 // XXX: check for AMD and set sVendor;
140 return B_OK;
144 status_t
145 disasm_arch_fini()
147 return B_OK;