Annotation of nono/debugger/debugger.h, revision 1.1.1.14

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.10  root       14: #include "bus.h"
1.1.1.6   root       15: #include "monitor.h"
1.1.1.9   root       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;    // マスク
1.1.1.14! root       75:                                int instbytes;  // 命令バイト数
1.1.1.9   root       76:                        };
                     77:                };
                     78: 
                     79:                uint32 matched {};              // 成立回数 (積算)
                     80: 
                     81:                // skip はユーザ指定値。ただし
                     82:                // -1 なら常にスキップ、つまりブレークせずカウントのみ行う、
                     83:                // 0 ならスキップなし、つまり成立ごとにブレーク(これがデフォルト)、
                     84:                // n(>0) なら n 回の成立をスキップし、(n+1) 回目でブレークの意。
                     85:                int32 skip {};                  // スキップ回数 (ユーザ指定値)
                     86:                int32 skipremain {};    // 残りスキップ回数 (0 で成立)
                     87:        };
                     88:        static const int MAX_BREAKPOINTS = 8;
                     89: 
                     90:        // ステップ実行種別
                     91:        enum StepType {
                     92:                None,                   // なし
                     93:                Count,                  // 命令数指定
                     94:                CountSkipSub,   // 命令数指定 (サブルーチンをスキップ)
                     95:                StepOut,                // ステップアウト
                     96:                Addr,                   // アドレス指定
                     97:                Time,                   // 時間指定
                     98:        };
                     99: 
                    100:  public:
                    101:        Debugger();
                    102:        ~Debugger() override;
                    103: 
                    104:        bool Create() override;
                    105:        void SetLogLevel(int) override;
                    106:        bool Init() override;
                    107:        void ThreadRun() override;
                    108:        void Terminate() override;
                    109: 
                    110:        void ExecMain() { Exec(md_mpu.get()); }
                    111:        void ExecXP()   { Exec(md_xp.get()); }
                    112: 
                    113:        // MPU トレースが必要なら true を返す
                    114:        bool IsTrace() const;
                    115: 
                    116:        // FILE コールバック
                    117:        int ReadFunc(char *, int);
                    118:        int WriteFunc(const char *, int);
                    119: 
                    120:  private:
                    121:        void Close();
1.1.1.12  root      122:        void RxCallback(uint32);
                    123:        void AcceptCallback(uint32);
1.1.1.9   root      124:        void Input(int);
                    125:        void EnterPrompt();
1.1.1.14! root      126:        void QuitPrompt();
1.1.1.9   root      127:        void LeavePrompt(bool trace);
                    128:        void PrintPrompt();
                    129: 
                    130:        void Exec(DebuggerMD *);
                    131:        CmdAct Command();
                    132:        bool CheckAllBreakpoints(DebuggerMD *);
1.1.1.14! root      133:        uint64 ReadBreakpointInst(breakpoint_t&);
1.1.1.9   root      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_D();
                    149:        CmdAct cmd_disp();
                    150:        CmdAct cmd_exhist();
                    151:        CmdAct cmd_h();
                    152:        CmdAct cmd_hb();
                    153:        CmdAct cmd_hr();
                    154:        CmdAct cmd_L();
                    155:        CmdAct cmd_m();
                    156:        CmdAct cmd_mpu();
                    157:        CmdAct cmd_M();
                    158:        CmdAct cmd_minus();
                    159:        CmdAct cmd_n();
                    160:        CmdAct cmd_nt();
1.1.1.14! root      161:        CmdAct cmd_pe();
        !           162:        CmdAct cmd_pf();
1.1.1.9   root      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 *);
1.1.1.13  root      175:        bool ParseOptBreakAddr(const std::string&);
                    176:        bool ParseOptBreakInst(const std::string&);
                    177:        bool ParseOptBreakVector(const std::string&);
                    178:        bool IsCPUStr(const std::string&) const;
1.1.1.9   root      179:        DebuggerMD *ParseCPU(const std::string&) const;
1.1.1.13  root      180:        int AddBreakInst(const std::string& cpustr, const std::string& inststr,
                    181:                const std::string& skipstr, std::string *errstr);
                    182:        int AddBreakVector(const std::string& cpustr, const std::string& vecstr,
                    183:                const std::string& skipstr, std::string *errstr);
                    184:        int AddBreakpoint(const breakpoint_t&);
1.1.1.10  root      185:        bool GetAddr(busaddr *addr, bool);
                    186:        CmdAct cmd_d_common(busaddr access_mode);
1.1.1.9   root      187:        CmdAct cmd_hist_common(BranchHistory& hist);
1.1.1.10  root      188:        CmdAct cmd_m_common(busaddr access_mode);
1.1.1.9   root      189:        CmdAct cmd_n_common(bool);
                    190:        CmdAct cmd_s_common(bool);
                    191:        CmdAct cmd_so_common(bool);
                    192:        bool ParseVector(DebuggerMD *, const char *arg, uint32 *valp);
                    193:        bool ParseVerbHex(const char *arg, uint32 *valp);
                    194:        bool ParseAddr(const char *arg, uint32_t *addrp);
                    195:        bool ParseTime(const char *arg, uint64 *timep);
                    196:        void SetNBreakpoint();
                    197:        void ChangeMD(DebuggerMD *);
                    198:        void ResetStickyAddr();
                    199: 
                    200:        static const HelpMessages HelpListMain;
                    201:        static const HelpMessages HelpListBreakpoints;
                    202:        static const HelpMessages HelpDetails;
                    203:        CmdAct ShowHelpList(const HelpMessages& msgs);
                    204: 
                    205:        // 個別ヘルプメッセージを出力用に置換
                    206:        std::string HelpConvert(const std::string& msg);
                    207: 
                    208:        // モニタを更新して表示
1.1.1.11  root      209:        void ShowMonitor(Monitor *monitor);
1.1.1.9   root      210:        // テキストスクリーンを表示
                    211:        void ShowTextScreen(TextScreen& screen);
                    212: 
                    213:        // 機種依存部分
                    214:        std::unique_ptr<DebuggerMD> md_mpu /*{}*/;      // メイン
                    215:        std::unique_ptr<DebuggerMD> md_xp /*{}*/;       // XP
                    216:        // 現行
                    217:        DebuggerMD *curmd {};
                    218: 
                    219:        std::mutex mtx {};
                    220:        // このスレッドへのリクエスト
                    221:        std::condition_variable cv_request {};
                    222:        uint32 request {};
                    223:        // コマンドモード(プロンプト)なら true
                    224:        std::condition_variable cv_prompt {};
                    225:        bool prompt_released {};
                    226: 
                    227:        bool is_prompt {};
                    228: 
                    229:        // コンソール
                    230:        std::unique_ptr<HostCOMDevice> hostcom /*{}*/;
                    231:        FILE *cons {};
                    232: 
                    233:        const char *prompt {};          // プロンプト文字列
                    234:        std::string cmdbuf {};          // 現在のコマンドライン
                    235:        std::string last_cmdbuf {};     // 直前のコマンドライン
1.1.1.13  root      236:        std::vector<std::string> cmdargs {};
1.1.1.9   root      237: 
                    238:        uint32 pc {};
                    239:        std::array<breakpoint_t, MAX_BREAKPOINTS> bpoint {};
                    240:        uint64 ct_timespan {};
1.1.1.10  root      241:        busaddr d_last_addr {};
                    242:        busaddr m_last_addr {};
1.1.1.9   root      243:        StepType step_type {};          // ステップ実行種別
                    244:        DebuggerMD *step_md {};         // ステップ実行中の CPU
                    245:        uint32 step_count {};
                    246:        uint64 step_addr {};
                    247:        uint64 step_time {};
                    248:        DebuggerMD *t_enable {};
                    249:        uint32 t_count {};
                    250: 
                    251:        // 一度VMを実行して再びプロンプトに来たら true
                    252:        bool is_continued {};
                    253: 
                    254:        // MPU を一時停止するとき true (ワンショット)
                    255:        bool is_pause {};
                    256: 
                    257:        // プロンプトで表示するレジスタ群
                    258:        std::vector<std::string> disp_regs {};
                    259: 
                    260:        // ブレークポイント到達メッセージ
                    261:        // (コンソールが獲得できるまで保留しておくため)
                    262:        std::string bpointmsg {};
                    263: 
                    264:        // ブレークポイントモニタ
1.1.1.14! root      265:        DECLARE_MONITOR_SCREEN(MonitorScreenBpoint);
1.1.1.11  root      266:        Monitor *bpoint_monitor {};
1.1.1.9   root      267: 
                    268:        // 逆アセンブルとメモリダンプモニタ
                    269:        std::array<std::unique_ptr<MemdumpMonitor>, MAX_MEMDUMP_MONITOR>
                    270:                memdump_monitor /*{}*/;
                    271:        std::array<std::unique_ptr<MemdumpMonitor>, MAX_XPMEMDUMP_MONITOR>
                    272:                xpmemdump_monitor /*{}*/;
                    273: 
                    274:        // ベクタテーブル
                    275:        std::unique_ptr<VectorTable> pVectorTable /*{}*/;
                    276: 
                    277:        Syncer *syncer {};
                    278: 
                    279:        static std::vector<cmddef_t> cmdtable;
                    280: };
                    281: 
1.1.1.14! root      282: inline Debugger *GetDebugger() {
1.1.1.9   root      283:        return Object::GetObject<Debugger>(OBJ_DEBUGGER);
                    284: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.