|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.7 root 7: //
8: // デバッガ (外部用)
9: //
10:
1.1 root 11: #pragma once
12:
1.1.1.9 ! root 13: #include "debugger_defs.h"
1.1.1.6 root 14: #include "monitor.h"
1.1.1.9 ! root 15: #include "saddr.h"
! 16: #include "textscreen.h"
! 17: #include "thread.h"
! 18: #include <array>
! 19: #include <condition_variable>
! 20: #include <mutex>
1.1.1.4 root 21:
1.1.1.9 ! root 22: class BranchHistory;
! 23: class HostCOMDevice;
! 24: class MemdumpMonitor;
! 25: class Syncer;
! 26: class VectorTable;
1.1.1.6 root 27:
1.1.1.9 ! root 28: class Debugger : public ThreadDevice
! 29: {
! 30: using inherited = ThreadDevice;
! 31: friend class DebuggerMD_m680x0;
! 32: friend class DebuggerMD_m88xx0;
! 33:
! 34: private:
! 35: // リクエストフラグ
! 36: static const uint32 REQUEST_EXIT = 0x0001; // 終了
! 37: static const uint32 REQUEST_RXCHAR = 0x0002; // 1文字受信
! 38: static const uint32 REQUEST_ACCEPT = 0x0004; // 着信通知
! 39: static const uint32 REQUEST_PROMPT = 0x0008; // プロンプト要求
! 40:
! 41: // コマンド
! 42: enum CmdAct {
! 43: Stay, // デバッガプロンプトに留まる
! 44: Leave, // デバッガプロンプトを抜けて VM を実行する
! 45: Quit, // デバッガとの接続を終了する
! 46: };
! 47: struct cmddef_t {
! 48: const char *name;
! 49: CmdAct (Debugger::*func)();
! 50: };
! 51:
! 52: // ブレークポイント種別
! 53: enum BreakpointType {
! 54: Unused = 0,
! 55: Address, // このアドレスに来る直前
! 56: Memory, // このアドレスをアクセスした直後
! 57: Exception, // この例外を検出した直後
! 58: Instruction, // この命令を実行する直前
! 59: };
! 60:
! 61: // ブレークポイント
! 62: struct breakpoint_t {
! 63: DebuggerMD *md {}; // CPU
! 64: BreakpointType type {}; // 種別
! 65: // 種別ごとのパラメータ
! 66: union {
! 67: uint32 addr {}; // ターゲットアドレス (Address/Memory)
! 68: struct {
! 69: int vec1; // ベクタ番号 (開始)
! 70: int vec2; // ベクタ番号 (終了)
! 71: };
! 72: struct {
! 73: uint32 inst; // 命令ワード
! 74: uint32 mask; // マスク
! 75: };
! 76: };
! 77:
! 78: uint32 matched {}; // 成立回数 (積算)
! 79:
! 80: // skip はユーザ指定値。ただし
! 81: // -1 なら常にスキップ、つまりブレークせずカウントのみ行う、
! 82: // 0 ならスキップなし、つまり成立ごとにブレーク(これがデフォルト)、
! 83: // n(>0) なら n 回の成立をスキップし、(n+1) 回目でブレークの意。
! 84: int32 skip {}; // スキップ回数 (ユーザ指定値)
! 85: int32 skipremain {}; // 残りスキップ回数 (0 で成立)
! 86: };
! 87: static const int MAX_BREAKPOINTS = 8;
! 88:
! 89: // ステップ実行種別
! 90: enum StepType {
! 91: None, // なし
! 92: Count, // 命令数指定
! 93: CountSkipSub, // 命令数指定 (サブルーチンをスキップ)
! 94: StepOut, // ステップアウト
! 95: Addr, // アドレス指定
! 96: Time, // 時間指定
! 97: };
! 98:
! 99: public:
! 100: Debugger();
! 101: ~Debugger() override;
! 102:
! 103: bool Create() override;
! 104: void SetLogLevel(int) override;
! 105: bool Init() override;
! 106: void ThreadRun() override;
! 107: void Terminate() override;
! 108:
! 109: void ExecMain() { Exec(md_mpu.get()); }
! 110: void ExecXP() { Exec(md_xp.get()); }
! 111: void NotifyExceptionMain(int vector);
! 112: void NotifyExceptionXP(int vector);
! 113:
! 114: // MPU トレースが必要なら true を返す
! 115: bool IsTrace() const;
! 116:
! 117: // FILE コールバック
! 118: int ReadFunc(char *, int);
! 119: int WriteFunc(const char *, int);
! 120:
! 121: private:
! 122: void Close();
! 123: void RxCallback();
! 124: void AcceptCallback();
! 125: void Input(int);
! 126: void EnterPrompt();
! 127: void LeavePrompt(bool trace);
! 128: void PrintPrompt();
! 129:
! 130: void Exec(DebuggerMD *);
! 131: CmdAct Command();
! 132: bool CheckAllBreakpoints(DebuggerMD *);
! 133: bool CheckBreakpointInst(breakpoint_t&);
! 134: void ParseCmdbuf();
! 135: // コマンド名は大文字小文字を区別する関係でスネークスタイル。
! 136: CmdAct cmd_b();
! 137: CmdAct cmd_bi();
! 138: CmdAct cmd_bm();
! 139: CmdAct cmd_bv();
! 140: CmdAct cmd_b_list();
! 141: CmdAct cmd_b_set(BreakpointType);
! 142: CmdAct cmd_b_delete();
! 143: CmdAct cmd_brhist();
! 144: CmdAct cmd_bx();
! 145: CmdAct cmd_c();
! 146: CmdAct cmd_ct();
! 147: CmdAct cmd_d();
! 148: CmdAct cmd_dt();
! 149: CmdAct cmd_D();
! 150: CmdAct cmd_disp();
! 151: CmdAct cmd_exhist();
! 152: CmdAct cmd_h();
! 153: CmdAct cmd_hb();
! 154: CmdAct cmd_hr();
! 155: CmdAct cmd_L();
! 156: CmdAct cmd_m();
! 157: CmdAct cmd_mt();
! 158: CmdAct cmd_mpu();
! 159: CmdAct cmd_M();
! 160: CmdAct cmd_minus();
! 161: CmdAct cmd_n();
! 162: CmdAct cmd_nt();
! 163: CmdAct cmd_q();
! 164: CmdAct cmd_reset();
! 165: CmdAct cmd_s();
! 166: CmdAct cmd_st();
! 167: CmdAct cmd_so();
! 168: CmdAct cmd_sot();
! 169: CmdAct cmd_show();
! 170: CmdAct cmd_t();
! 171: CmdAct cmd_xp();
! 172: CmdAct cmd_z();
! 173:
! 174: bool Check(DebuggerMD *);
! 175: DebuggerMD *ParseCPU(const std::string&) const;
! 176: int AddBreakpoint(const breakpoint_t&, const std::string&);
! 177: void RecalcInstMask();
! 178: bool GetAddr(saddr_t *addr, bool);
! 179: CmdAct cmd_d_common(MemoryMode access_mode, MMULookupMode lookup_mode);
! 180: CmdAct cmd_hist_common(BranchHistory& hist);
! 181: CmdAct cmd_m_common(MemoryMode access_mode, MMULookupMode lookup_mode);
! 182: CmdAct cmd_n_common(bool);
! 183: CmdAct cmd_s_common(bool);
! 184: CmdAct cmd_so_common(bool);
! 185: bool ParseVector(DebuggerMD *, const char *arg, uint32 *valp);
! 186: bool ParseVerbHex(const char *arg, uint32 *valp);
! 187: bool ParseAddr(const char *arg, uint32_t *addrp);
! 188: bool ParseTime(const char *arg, uint64 *timep);
! 189: void SetNBreakpoint();
! 190: void ChangeMD(DebuggerMD *);
! 191: void ResetStickyAddr();
! 192:
! 193: static const HelpMessages HelpListMain;
! 194: static const HelpMessages HelpListBreakpoints;
! 195: static const HelpMessages HelpDetails;
! 196: CmdAct ShowHelpList(const HelpMessages& msgs);
! 197:
! 198: // 個別ヘルプメッセージを出力用に置換
! 199: std::string HelpConvert(const std::string& msg);
! 200:
! 201: // モニタを更新して表示
! 202: void ShowMonitor(Monitor& monitor);
! 203: // テキストスクリーンを表示
! 204: void ShowTextScreen(TextScreen& screen);
! 205:
! 206: // 機種依存部分
! 207: std::unique_ptr<DebuggerMD> md_mpu /*{}*/; // メイン
! 208: std::unique_ptr<DebuggerMD> md_xp /*{}*/; // XP
! 209: // 現行
! 210: DebuggerMD *curmd {};
! 211:
! 212: std::mutex mtx {};
! 213: // このスレッドへのリクエスト
! 214: std::condition_variable cv_request {};
! 215: uint32 request {};
! 216: // コマンドモード(プロンプト)なら true
! 217: std::condition_variable cv_prompt {};
! 218: bool prompt_released {};
! 219:
! 220: bool is_prompt {};
! 221:
! 222: // コンソール
! 223: std::unique_ptr<HostCOMDevice> hostcom /*{}*/;
! 224: FILE *cons {};
! 225:
! 226: const char *prompt {}; // プロンプト文字列
! 227: std::string cmdbuf {}; // 現在のコマンドライン
! 228: std::string last_cmdbuf {}; // 直前のコマンドライン
! 229: std::vector<std::string> args {};
! 230:
! 231: uint32 pc {};
! 232: std::array<breakpoint_t, MAX_BREAKPOINTS> bpoint {};
! 233: uint32 bi_inst {};
! 234: int bi_inst_bytes {};
! 235: int bi_need_bytes {};
! 236: uint64 ct_timespan {};
! 237: saddr_t d_last_addr {};
! 238: saddr_t m_last_addr {};
! 239: StepType step_type {}; // ステップ実行種別
! 240: DebuggerMD *step_md {}; // ステップ実行中の CPU
! 241: uint32 step_count {};
! 242: uint64 step_addr {};
! 243: uint64 step_time {};
! 244: DebuggerMD *t_enable {};
! 245: uint32 t_count {};
! 246:
! 247: // 一度VMを実行して再びプロンプトに来たら true
! 248: bool is_continued {};
! 249:
! 250: // MPU を一時停止するとき true (ワンショット)
! 251: bool is_pause {};
! 252:
! 253: // プロンプトで表示するレジスタ群
! 254: std::vector<std::string> disp_regs {};
! 255:
! 256: // ブレークポイント到達メッセージ
! 257: // (コンソールが獲得できるまで保留しておくため)
! 258: std::string bpointmsg {};
! 259:
! 260: // ブレークポイントモニタ
! 261: DECLARE_MONITOR_CALLBACK(MonitorUpdateBpoint);
! 262: Monitor bpoint_monitor { this };
! 263:
! 264: // 逆アセンブルとメモリダンプモニタ
! 265: std::array<std::unique_ptr<MemdumpMonitor>, MAX_MEMDUMP_MONITOR>
! 266: memdump_monitor /*{}*/;
! 267: std::array<std::unique_ptr<MemdumpMonitor>, MAX_XPMEMDUMP_MONITOR>
! 268: xpmemdump_monitor /*{}*/;
! 269:
! 270: // ベクタテーブル
! 271: std::unique_ptr<VectorTable> pVectorTable /*{}*/;
! 272:
! 273: Syncer *syncer {};
! 274:
! 275: static std::vector<cmddef_t> cmdtable;
! 276: };
! 277:
! 278: static inline Debugger *GetDebugger() {
! 279: return Object::GetObject<Debugger>(OBJ_DEBUGGER);
! 280: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.