99 lines
2.6 KiB
C++
99 lines
2.6 KiB
C++
#ifndef _SDB_SDB_HEADER_FILE_
|
|
#define _SDB_SDB_HEADER_FILE_
|
|
|
|
#include <components.hpp>
|
|
#include <console.hpp>
|
|
#include <memory>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <trm_interface.hpp>
|
|
#include <types.h>
|
|
|
|
namespace cr = CppReadline;
|
|
using ret = cr::Console::ReturnCode;
|
|
|
|
namespace SDB {
|
|
|
|
enum SDBStatus {
|
|
SDB_SUCCESS,
|
|
SDB_EBREAK = 2,
|
|
SDB_WRONG_ARGUMENT,
|
|
SDB_DIFFTEST_FAILED
|
|
};
|
|
|
|
class SDBHandlers;
|
|
|
|
struct Handler {
|
|
const std::vector<const char *> names;
|
|
// cr::Console::CommandFunction f;
|
|
std::function<int(SDBHandlers *, const cr::Console::Arguments &)> f;
|
|
};
|
|
|
|
class SDBHandlers {
|
|
private:
|
|
const TrmInterface &funcs;
|
|
std::vector<Handler> all_handlers = {
|
|
Handler{{"c", "continue"}, &SDBHandlers::cmd_continue},
|
|
Handler{{"si", "step-instruction"}, &SDBHandlers::cmd_step},
|
|
Handler{{"info-r"}, &SDBHandlers::cmd_info_registers},
|
|
Handler{{"p", "print"}, &SDBHandlers::cmd_print},
|
|
Handler{{"disas", "disassemble"}, &SDBHandlers::cmd_disassemble},
|
|
};
|
|
int cmd_continue(const cr::Console::Arguments &input);
|
|
int cmd_step(const std::vector<std::string> &input);
|
|
int cmd_info_registers(const std::vector<std::string> &input);
|
|
int cmd_print(const std::vector<std::string> &input);
|
|
int cmd_disassemble(const std::vector<std::string> &input);
|
|
int exec_catch(uint64_t);
|
|
|
|
public:
|
|
SDBHandlers(const TrmInterface &funcs) : funcs(funcs){};
|
|
void register_handlers(cr::Console *c);
|
|
};
|
|
|
|
class SDB {
|
|
private:
|
|
std::unique_ptr<CppReadline::Console> c;
|
|
const TrmInterface &funcs;
|
|
SDBHandlers handlers;
|
|
|
|
public:
|
|
SDB(const TrmInterface &funcs,
|
|
std::string const &greeting = "\033[1;34m(npc)\033[0m ")
|
|
: handlers(SDBHandlers{funcs}), funcs(funcs) {
|
|
c = std::make_unique<CppReadline::Console>(greeting);
|
|
|
|
handlers.register_handlers(c.get());
|
|
};
|
|
|
|
int main_loop() {
|
|
int ret_code;
|
|
funcs.init(0);
|
|
std::vector<std::string> step_commands{"c", "continue", "si",
|
|
"step-instruction"};
|
|
do {
|
|
ret_code = c->readLine();
|
|
// We can also change the prompt based on last return value:
|
|
if (ret_code == SDB_SUCCESS || ret_code == SDB_EBREAK)
|
|
c->setGreeting("\033[1;34m(npc)\033[0m ");
|
|
else
|
|
c->setGreeting("\033[1;31m(npc)\033[0m ");
|
|
|
|
switch (ret_code) {
|
|
case SDB_EBREAK: {
|
|
std::cout << "\033[1;31m=== ebreak ===\033[0m" << std::endl;
|
|
c->removeCommands(step_commands);
|
|
break;
|
|
}
|
|
case SDB_WRONG_ARGUMENT: {
|
|
std::cout << "Wrong argument(s) is given to command handler\n";
|
|
break;
|
|
}
|
|
}
|
|
} while (ret_code != ret::Quit);
|
|
return 0;
|
|
}
|
|
};
|
|
} // namespace SDB
|
|
|
|
#endif
|