From 4ffaf2cef3b9ecb9ad2c050ddc84d106ea20d848 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 15:24:34 +0200 Subject: [PATCH] Add simple command-line debugger. --- CMakeLists.txt | 4 +- debugger.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ debugger.h | 6 +++ main.cpp | 3 ++ makefile | 11 +++-- 5 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 debugger.cpp create mode 100644 debugger.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a31f0e5..aad0f61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ set(SOURCE_FILES viacuda.cpp main.cpp davbus.cpp + debugger.cpp ) set(HEADER_FILES @@ -33,7 +34,8 @@ set(HEADER_FILES ppcmemory.h viacuda.h davbus.h + debugger.h ) add_executable(dingusppc ${SOURCE_FILES} ${HEADER_FILES}) -install (TARGETS dingusppc DESTINATION bin) \ No newline at end of file +install (TARGETS dingusppc DESTINATION bin) diff --git a/debugger.cpp b/debugger.cpp new file mode 100644 index 0000000..3010aeb --- /dev/null +++ b/debugger.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include "ppcemumain.h" +#include "ppcmemory.h" + + +using namespace std; + +void show_help() +{ + cout << "Debugger commands:" << endl; + cout << " step -- execute single instruction" << endl; + cout << " until X -- execute until address X is reached" << endl; + cout << " regs -- dump content of the GRPs" << endl; + cout << " disas X,n -- disassemble N instructions starting at address X" << endl; + cout << " quit -- quit the debugger" << endl << endl; + cout << "Pressing ENTER will repeat last command." << endl; +} + +void dump_regs() +{ + for (uint32_t i = 0; i < 32; i++) + cout << "GPR " << dec << i << " : " << hex << ppc_state.ppc_gpr[i] << endl; + + cout << "PC: " << hex << ppc_state.ppc_pc << endl; + cout << "LR: " << hex << ppc_state.ppc_spr[8] << endl; + cout << "CR: " << hex << ppc_state.ppc_cr << endl; + cout << "CTR: " << hex << ppc_state.ppc_spr[9] << endl; + cout << "XER: " << hex << ppc_state.ppc_spr[1] << endl; + cout << "MSR: " << hex << ppc_state.ppc_msr << endl; +} + +void execute_single_instr() +{ + quickinstruction_translate(ppc_state.ppc_pc); + //cout << "Current instruction: " << hex << ppc_cur_instruction << endl; + ppc_main_opcode(); + if (grab_branch && !grab_exception) { + //cout << "Grab branch, EA: " << hex << ppc_next_instruction_address << endl; + ppc_state.ppc_pc = ppc_next_instruction_address; + grab_branch = 0; + ppc_tbr_update(); + } + else if (grab_return || grab_exception) { + ppc_state.ppc_pc = ppc_next_instruction_address; + grab_exception = 0; + grab_return = 0; + ppc_tbr_update(); + } + else { + ppc_state.ppc_pc += 4; + ppc_tbr_update(); + } + ppc_cur_instruction = 0; +} + +void execute_until(uint32_t goal_addr) +{ + while(ppc_state.ppc_pc != goal_addr) + execute_single_instr(); +} + +void enter_debugger() +{ + string inp, cmd, addr_str, last_cmd; + uint32_t addr; + std::stringstream ss; + + cout << "Welcome to the PowerPC debugger." << endl; + cout << "Please enter a command or 'help'." << endl << endl; + + while (1) { + cout << "ppcdbg> "; + + /* reset string stream */ + ss.str(""); + ss.clear(); + + cmd = ""; + getline(cin, inp, '\n'); + ss.str(inp); + ss >> cmd; + + if (cmd.empty() && !last_cmd.empty()) { + cmd = last_cmd; + cout << cmd << endl; + } + if (cmd == "help") { + show_help(); + } else if (cmd == "quit") { + break; + } else if (cmd == "regs") { + dump_regs(); + } else if (cmd == "step") { + execute_single_instr(); + } else if (cmd == "until") { + ss >> addr_str; + addr = stol(addr_str, NULL, 16); + execute_until(addr); + } else if (cmd == "disas") { + cout << "Disassembling not implemented yet. Sorry!" << endl; + } else { + cout << "Unknown command: " << cmd << endl; + continue; + } + last_cmd = cmd; + } +} diff --git a/debugger.h b/debugger.h new file mode 100644 index 0000000..b278ea9 --- /dev/null +++ b/debugger.h @@ -0,0 +1,6 @@ +#ifndef DEBUGGER_H_ +#define DEBUGGER_H_ + +void enter_debugger(void); + +#endif // DEBUGGER_H_ diff --git a/main.cpp b/main.cpp index 8abe295..17641e5 100644 --- a/main.cpp +++ b/main.cpp @@ -25,6 +25,7 @@ #include "viacuda.h" #include "mpc106.h" #include "openpic.h" +#include "debugger.h" //#include #define max_16b_int 65535 @@ -846,6 +847,8 @@ int main(int argc, char **argv) ppc_cur_instruction = 0; } } + } else if (checker == "debugger") { + enter_debugger(); } } else{ diff --git a/makefile b/makefile index a20d720..cc2c726 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ -OBJS = main.o macioserial.o macscsi.o macswim3.o mpc106.o openpic.o poweropcodes.o ppcfpopcodes.o ppcgekkoopcodes.o ppcmemory.o ppcopcodes.o viacuda.o davbus.o -SOURCE = main.cpp macioserial.cpp macscsi.cpp macswim3.cpp mpc106.cpp openpic.cpp poweropcodes.cpp ppcfpopcodes.cpp ppcgekkoopcodes.cpp ppcmemory.cpp ppcopcodes.cpp viacuda.cpp davbus.cpp -HEADER = macioserial.h macscsi.h macswim3.h mpc106.h openpic.h ppcemumain.h ppcmemory.h viacuda.h +OBJS = main.o macioserial.o macscsi.o macswim3.o mpc106.o openpic.o poweropcodes.o ppcfpopcodes.o ppcgekkoopcodes.o ppcmemory.o ppcopcodes.o viacuda.o davbus.o debugger.o +SOURCE = main.cpp macioserial.cpp macscsi.cpp macswim3.cpp mpc106.cpp openpic.cpp poweropcodes.cpp ppcfpopcodes.cpp ppcgekkoopcodes.cpp ppcmemory.cpp ppcopcodes.cpp viacuda.cpp davbus.cpp debugger.cpp +HEADER = macioserial.h macscsi.h macswim3.h mpc106.h openpic.h ppcemumain.h ppcmemory.h viacuda.h debugger.h OUT = dingusppc CC = g++ FLAGS = -g -c -Wall -std=c++11 @@ -46,7 +46,10 @@ viacuda.o: viacuda.cpp $(CC) $(FLAGS) viacuda.cpp davbus.o: davbus.cpp - $(CC) $(FLAGS) davbus.cpp + $(CC) $(FLAGS) davbus.cpp + +debugger.o: debugger.cpp + $(CC) $(FLAGS) debugger.cpp clean: rm -f $(OBJS) $(OUT)