mirror of
https://github.com/daeken/Zookeeper.git
synced 2024-05-15 11:29:33 -04:00
136 lines
3.6 KiB
C++
136 lines
3.6 KiB
C++
#include "Zookeeper.hpp"
|
|
#include <boost/algorithm/string.hpp>
|
|
#include <boost/regex.hpp>
|
|
using namespace boost::algorithm;
|
|
|
|
void break_in(bool fatal) {
|
|
if(fatal)
|
|
box->cpu->stop = true;
|
|
else
|
|
box->cpu->do_break_in = true;
|
|
}
|
|
|
|
Breakpoint::Breakpoint(uint32_t _addr) : addr(_addr) {
|
|
enable();
|
|
}
|
|
|
|
void Breakpoint::enable() {
|
|
if(enabled)
|
|
return;
|
|
saved = box->cpu->read_memory<uint8_t>(addr);
|
|
box->cpu->write_memory<uint8_t>(addr, 0xCC);
|
|
box->cpu->invalidate_tlb();
|
|
enabled = true;
|
|
}
|
|
|
|
void Breakpoint::disable() {
|
|
if(!enabled)
|
|
return;
|
|
box->cpu->write_memory(addr, saved);
|
|
box->cpu->invalidate_tlb();
|
|
enabled = false;
|
|
}
|
|
|
|
Debugger::Debugger() {
|
|
}
|
|
|
|
#define MAX_FRAMES 8
|
|
void Debugger::stack_trace() {
|
|
cout << "Stack trace:" << endl;
|
|
|
|
auto ebp = box->cpu->hv->reg(EBP);
|
|
for(auto i = 0; i < MAX_FRAMES; ++i) {
|
|
if(ebp == 0)
|
|
break;
|
|
auto eip = box->cpu->read_memory<uint32_t>(ebp + 4);
|
|
cout << hex << eip << endl;
|
|
ebp = box->cpu->read_memory<uint32_t>(ebp);
|
|
}
|
|
|
|
cout << endl;
|
|
}
|
|
|
|
#define MAX_LENGTH 20
|
|
void Debugger::dump_stack() {
|
|
auto esp = box->cpu->hv->reg(ESP);
|
|
for(auto i = 0; i < MAX_LENGTH; ++i)
|
|
cout << format("%08x") % box->cpu->read_memory<uint32_t>(esp + i * 4) << endl;
|
|
}
|
|
|
|
void Debugger::enter(uint32_t reason) {
|
|
auto eip = box->cpu->hv->reg(EIP);
|
|
|
|
if(IN(eip, breakpoints)) {
|
|
cout << format("Hit breakpoint at 0x%08x") % eip << endl;
|
|
breakpoints[eip]->disable();
|
|
box->cpu->single_step = 1;
|
|
}
|
|
|
|
while(1) {
|
|
cout << format("[%i] %08x > ") % box->tm->current_thread() % eip << flush;
|
|
|
|
string line;
|
|
if(!getline(cin, line)) {
|
|
cout << endl;
|
|
exit(0);
|
|
}
|
|
line = boost::regex_replace(line, boost::regex("[\\s]{2,}"), " ");
|
|
|
|
vector<string> v;
|
|
split(v, line, is_space());
|
|
if(v.size() == 0 || v[0] == "")
|
|
continue;
|
|
|
|
auto cmd = v[0];
|
|
if(cmd == "c" || cmd == "cont" || cmd == "continue")
|
|
break;
|
|
else if(cmd == "s" || cmd == "step") {
|
|
box->cpu->single_step = 2;
|
|
break;
|
|
} else if(cmd == "b" || cmd == "bp" || cmd == "break") {
|
|
assert(v.size() >= 2);
|
|
auto addr = stoul(v[1], nullptr, 16);
|
|
if(IN(addr, breakpoints))
|
|
cout << format("Breakpoint already exists at %08x") % addr << endl;
|
|
else {
|
|
breakpoints[addr] = new Breakpoint(addr);
|
|
cout << format("Added breakpoint at addr %08x") % addr << endl;
|
|
}
|
|
} else if(cmd == "trace") {
|
|
stack_trace();
|
|
} else if(cmd == "stack") {
|
|
dump_stack();
|
|
} else if(cmd == "r" || cmd == "regs") {
|
|
cout << format("eax %08x ebx %08x") % box->cpu->hv->reg(EAX) % box->cpu->hv->reg(EBX) << endl;
|
|
cout << format("ecx %08x edx %08x") % box->cpu->hv->reg(ECX) % box->cpu->hv->reg(EDX) << endl;
|
|
cout << format("edi %08x esi %08x") % box->cpu->hv->reg(EDI) % box->cpu->hv->reg(ESI) << endl;
|
|
cout << format("ebp %08x esp %08x") % box->cpu->hv->reg(EBP) % box->cpu->hv->reg(ESP) << endl;
|
|
cout << format("eflags %08x") % box->cpu->hv->reg(EFLAGS) << endl;
|
|
} else if(cmd == "rm" || cmd == "read") {
|
|
string type = "u32";
|
|
auto offset = 1;
|
|
if(v.size() == 3) {
|
|
type = v[1];
|
|
offset = 2;
|
|
}
|
|
auto addr = stoul(v[offset], nullptr, 16);
|
|
if(type == "u8")
|
|
cout << format("*0x%08x == 0x%02x") % addr % (uint32_t) box->cpu->read_memory<uint8_t>(addr) << endl;
|
|
else if(type == "u16")
|
|
cout << format("*0x%08x == 0x%04x") % addr % (uint32_t) box->cpu->read_memory<uint16_t>(addr) << endl;
|
|
else if(type == "u32")
|
|
cout << format("*0x%08x == 0x%08x") % addr % box->cpu->read_memory<uint32_t>(addr) << endl;
|
|
else
|
|
cout << "Unknown type (try u8, u16, or u32)" << endl;
|
|
} else {
|
|
cout << "Unknown command" << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Debugger::reenable() {
|
|
for(auto bp : breakpoints) {
|
|
bp.second->enable();
|
|
}
|
|
}
|