さて、前回でGDBのリモートデバッグプロトコルについて分かってきた。 今度は、これを実装していこう。
基本的には、OpenRISCのISSであるor1ksimの実装を参考にする。 といっても、or1ksimはC言語で実装してあるので、必要な部分はC++に置き換えていく必要がありそうだ。 (と言っても大部分のアルゴリズムは変更しようが無いのだが...なのでほとんどパクってしまうことになるかもしれない)
GDBインタフェース用のクラスを追加する
僕のISSは、CPUのコア部分と、それを操作する外回りのクラス群で構成されている。コアの部分は、CPUの内部機能などを司っているので、GDBインタフェースを追加することには影響しない。 コアの外回りに、新しいインタフェースとしてGDBのクラスを追加するだけだ。
GdbEnvクラスを追加して、まずは初期化とポート開放をするメソッドを実装しよう。
class GdbEnv { private: EnvBase *m_env; std::unique_ptr<GdbServer> m_gdb_server; uint32_t m_serial_port; public: GdbEnv (EnvBase *env); void HandleGdb (); void GetClientPort (); std::vector<mp_entry> m_vec_mp_entry; };
mp_entryとか、まだor1ksimのコードをコピっただけなので、理解できていない部分が多い。。。
ポートを開放する
GDBインタフェースについても、基本的にor1ksimと同じものを踏襲した。 (本来ならばor1ksimのインタフェースをライブラリとして使用したいところだが、C++の実装とうまく合わないし、切り出すのも難しいため、現在のところ実装を殆ど真似る状態となっている。。。)
void GdbEnv::GetClientPort (void) { int tmp_fd; /* Temporary descriptor for socket */ int optval; /* Socket options */ struct sockaddr_in sock_addr; /* Socket address */ socklen_t len; /* Size of the socket address */ /* 0 is used as the RSP port number to indicate that we should use the service name instead. */ m_serial_port = 2000; if (m_serial_port == 0) { struct servent *service = getservbyname (MIPS64_RSP_SERVICE, "tcp"); if (service == NULL) { std::cerr << "Warning: RSP unable to find service \"" << MIPS64_RSP_SERVICE "\": strerror (errno)\n"; return; } m_serial_port = ntohs (service->s_port); } ...
m_serial_port = 2000となっているのがお分かりだろうか?今のところ、ポートは2000で決め打ちになっている(笑)
GDBポートを指定するフラグの追加
ISSのコマンドラインオプションに、GDBの受付ポートを指定するオプションを追加する。ISSにはコマンドラインオプション解析としてGoogle Flagsを利用しているので、この辺りの拡張は非常に簡単だ。
DEFINE_bool (gdb, false, "Wait GDB port"); ... if (FLAGS_gdb == true) { #ifdef ARCH_MIPS64 Mips64Env *env = new Mips64Env (g_debug_fp, g_uart_fp, en_stop_sim, FLAGS_debug); #endif // ARCH_MIPS64 std::unique_ptr<GdbEnv> p_gdb = std::unique_ptr<GdbEnv>(new GdbEnv(env)); p_gdb->HandleGdb();
これだけで、--gdb port引数を付けると、GDBの待受モードに(とりあえず)入ることができる。
$ ./swimmer_mips64 --gdb Swimmer-RISCV Version 20160118 Revision 5858f70 developed by Masayuki Kimura <masayuki.kimura.1986@gmail.com> Listening for RSP on port 2000