Annotation of nono/debugger/debugger_private.h, revision 1.1.1.3

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
1.1.1.3 ! root        9: #include "branchhistory.h"
1.1       root       10: #include "bus.h"
                     11: #include "cvprompt.h"
                     12: #include "textscreen.h"
1.1.1.2   root       13: #include <array>
                     14: 
                     15: using ConstStringPair = std::pair<const std::string, const std::string>;
                     16: using HelpMessages = std::vector<ConstStringPair>;
1.1       root       17: 
                     18: // 諸情報付きのアドレス
                     19: struct saddr_t
                     20: {
                     21:        uint32 addr = 0;                // アドレス(32bit)
                     22: 
                     23:        // addr が論理アドレスなら true。
                     24:        // MMU の有効/無効状態はここにセットするのではなく、メモリアクセスに
                     25:        // 際してアドレス変換を行う側がその時点で改めてチェックするので、
                     26:        // ここはどちらかというと物理アドレスなら false くらいの意味合い。
                     27:        bool logical = false;
                     28: 
                     29:        // addr が論理アドレスの場合に、テーブルサーチも行うなら true。
                     30:        // false なら TT、ATC のみ検索する。
                     31:        bool search = false;
                     32: 
                     33:        // addr がスーパバイザアクセスなら true。
                     34:        bool super = false;
                     35: 
                     36:        // addr がデータアクセスなら true。
                     37:        bool data = false;
                     38: 
                     39:        bool IsLogical() const  { return logical; }
                     40:        bool IsSearch() const   { return search; }
                     41:        bool IsSuper() const    { return super; }
                     42:        bool IsData() const             { return data; }
                     43:        bool IsInst() const             { return !data; }
                     44: 
                     45:        // (論理)アドレスと Super/User ビットを合わせた 33bit アドレスを返す
                     46:        uint64 GetSaddr() const {
                     47:                uint64 sa = addr;
                     48:                if (IsSuper()) {
                     49:                        sa |= 0x100000000ULL;
                     50:                }
                     51:                return sa;
                     52:        }
                     53: };
                     54: 
                     55: enum MemdumpMode {
                     56:        Physical = 0,           // 物理アドレス
                     57:        Logical_atc,            // 論理アドレス (ただし TT、ATC のみ検索)
                     58:        Logical_search,         // 論理アドレス (TT、ATC、テーブルサーチすべて行う)
                     59: };
                     60: 
                     61: class Console;
                     62: class DebuggerMD;
                     63: class Disasm;
                     64: 
1.1.1.2   root       65: class Debugger final
1.1       root       66: {
                     67:        friend class DebuggerMD_m680x0;
                     68:        friend class DebuggerMD_m88xx0;
                     69:  private:
                     70:        // 型
1.1.1.2   root       71:        enum CommandAction {
                     72:                Stay,           // デバッガプロンプトに留まる
                     73:                Leave,          // デバッガプロンプトを抜けて VM を実行する
                     74:                Quit,           // デバッガとの接続を終了する
                     75:        };
                     76:        using cmdfunc_t = void (Debugger::*)();
1.1       root       77:        typedef struct {
                     78:                const char *name;
                     79:                cmdfunc_t func;
1.1.1.2   root       80:                CommandAction action;
1.1       root       81:        } cmddef_t;
                     82: 
1.1.1.3 ! root       83:        // ブレークポイント種別
        !            84:        enum BreakpointType {
        !            85:                Unused = 0,
        !            86:                Address,                // このアドレスに来る直前
        !            87:                Memory,                 // このアドレスをアクセスした直後
        !            88:                Exception,              // この例外を検出した直後
        !            89:                Instruction,    // この命令を実行する直前
        !            90:        };
        !            91: 
1.1       root       92:        // ブレークポイント
                     93:        typedef struct {
1.1.1.3 ! root       94:                BreakpointType type {}; // 種別
        !            95:                // 種別ごとのパラメータ
        !            96:                union {
        !            97:                        uint32 addr {};         // ターゲットアドレス (Address/Memory)
        !            98:                        struct {
        !            99:                                int vec1;               // ベクタ番号 (開始)
        !           100:                                int vec2;               // ベクタ番号 (終了)
        !           101:                        };
        !           102:                        struct {
        !           103:                                uint32 inst;    // 命令ワード
        !           104:                                uint32 mask;    // マスク
        !           105:                        };
        !           106:                };
        !           107: 
        !           108:                uint32 matched {};              // 成立回数 (積算)
        !           109: 
        !           110:                // skip はユーザ指定値。ただし
        !           111:                // -1 なら常にスキップ、つまりブレークせずカウントのみ行う、
        !           112:                // 0 ならスキップなし、つまり成立ごとにブレーク(これがデフォルト)、
        !           113:                // n(>0) なら n 回の成立をスキップし、(n+1) 回目でブレークの意。
        !           114:                int32 skip {};                  // スキップ回数 (ユーザ指定値)
        !           115:                int32 skipremain {};    // 残りスキップ回数 (0 で成立)
1.1       root      116:        } breakpoint_t;
                    117:        static const int MAX_BREAKPOINTS = 8;
                    118: 
                    119:  public:
                    120:        Debugger();
1.1.1.2   root      121:        ~Debugger() { }
1.1       root      122: 
                    123:        void Init();
                    124:        void ThreadRun();
                    125:        bool Check();
1.1.1.3 ! root      126:        void NotifyException(int vector);
        !           127: 
        !           128:        // ブレークポイントモニタを更新
        !           129:        void MonitorBreakpoint(TextScreen& monitor);
1.1       root      130: 
                    131:  private:
1.1.1.2   root      132:        bool Accept();
                    133:        bool AcquirePrompt();
                    134:        CommandAction MainLoop();
1.1.1.3 ! root      135:        bool CheckAllBreakpoints();
        !           136:        bool CheckBreakpointInst(breakpoint_t&);
1.1.1.2   root      137:        void ParseCmdbuf();
1.1       root      138:        // コマンド名は大文字小文字を区別する関係でスネークスタイル。
                    139:        void cmd_b();
1.1.1.3 ! root      140:        void cmd_bi();
        !           141:        void cmd_bm();
        !           142:        void cmd_bv();
1.1       root      143:        void cmd_b_list();
1.1.1.3 ! root      144:        void cmd_b_set(BreakpointType);
1.1       root      145:        void cmd_brhist();
                    146:        void cmd_bx();
                    147:        void cmd_c();
                    148:        void cmd_d();
                    149:        void cmd_dt();
                    150:        void cmd_D();
1.1.1.3 ! root      151:        void cmd_exhist();
1.1       root      152:        void cmd_h();
                    153:        void cmd_L();
                    154:        void cmd_m();
                    155:        void cmd_mt();
                    156:        void cmd_M();
                    157:        void cmd_minus();
                    158:        void cmd_n();
                    159:        void cmd_q();
                    160:        void cmd_s();
                    161:        void cmd_so();
                    162:        void cmd_show();
                    163:        void cmd_t();
                    164: 
1.1.1.3 ! root      165:        int AddBreakpoint(const breakpoint_t&);
        !           166:        void RecalcInstMask();
1.1       root      167:        bool GetAddr(uint32& addr, uint32& lastaddr);
                    168:        void cmd_d_common(MemdumpMode mode);
1.1.1.3 ! root      169:        void cmd_hist_common(BranchHistory& hist, uint64 flag);
1.1       root      170:        void cmd_m_common(MemdumpMode mode);
1.1.1.3 ! root      171:        bool ParseVerbHex(const char *arg, uint32 *valp);
1.1       root      172:        bool ParseAddr(const char *arg, uint32_t *addrp);
                    173:        bool SetNBreakpoint();
                    174: 
1.1.1.2   root      175:        static const HelpMessages HelpMsgMain;
                    176:        void Help(const HelpMessages msgs);
                    177: 
                    178:        // モニターを更新して表示
1.1.1.3 ! root      179:        void ShowMonitor(IMonitor& monitor);
1.1.1.2   root      180:        // テキストスクリーンを表示
                    181:        void ShowTextScreen(TextScreen& screen);
1.1       root      182: 
                    183:        // アドレスをダンプ表示用に整形して返す
                    184:        bool FormatDumpAddr(saddr_t addr, std::string& addrstr);
                    185: 
                    186:        DebuggerMD *md = NULL;          // 機種依存部分
                    187: 
                    188:        Console *cons = NULL;           // 入出力
                    189:        const char *prompt;                     // プロンプト文字列
                    190:        std::string cmdbuf {};          // 現在のコマンドライン
                    191:        std::string last_cmdbuf {};     // 直前のコマンドライン
1.1.1.2   root      192:        std::vector<std::string> args {};
1.1       root      193: 
                    194:        uint32 pc = 0;
                    195:        uint32 nextpc = 0;
                    196:        std::vector<uint8> ir {};       // この後実行する命令のバイナリ列
1.1.1.2   root      197:        std::array<breakpoint_t, MAX_BREAKPOINTS> bpoint {};
1.1       root      198:        bool bc_enable = false;
                    199:        uint32 bc_addr = 0;
1.1.1.3 ! root      200:        uint32 bi_inst = 0;
        !           201:        int bi_inst_bytes = 0;
        !           202:        int bi_need_bytes = 0;
        !           203:        int bv_vector = -1;
1.1       root      204:        uint32 d_last_addr = 0;
                    205:        uint32 m_last_addr = 0;
                    206:        bool n_enable = false;
                    207:        bool n_breakenable = false;
                    208:        uint32 n_breakaddr = 0;
                    209:        uint32 n_count = 0;
                    210:        bool s_enable = false;
                    211:        uint32 s_count = 0;
                    212:        bool so_enable = false;
                    213:        bool t_enable = false;
                    214:        uint32 t_count = 0;
                    215: 
                    216:        // 一度VMを実行して再びプロンプトに来たら true
                    217:        bool is_continued = false;
                    218: 
1.1.1.2   root      219:        static std::vector<cmddef_t> cmdtable;
1.1       root      220: };
                    221: 
                    222: // デバッガの CPU 依存部分
                    223: class DebuggerMD
                    224: {
                    225:  public:
                    226:        DebuggerMD(Debugger *arg) {
                    227:                parent = arg;
                    228:        }
                    229:        virtual ~DebuggerMD() { }
                    230: 
                    231:        // CPU のリクエストフラグに flag を立てる
                    232:        virtual void ReqSet(uint32 flag) = 0;
                    233:        // CPU のリクエストフラグから flag を落とす
                    234:        virtual void ReqClr(uint32 flag) = 0;
                    235: 
                    236:        // 特権モードなら true を返す
                    237:        virtual bool IsSuper() const = 0;
                    238:        // MMU が有効なら true を返す
                    239:        virtual bool MMUEnabled() const = 0;
                    240: 
                    241:        // アドレス変換をする。
                    242:        // MMUEnabled() が true であることは呼び出し側が確認すること。
                    243:        // 変換できなければ (uint64)-1 を返す。
                    244:        virtual uint64 TranslateAddr(saddr_t laddr) = 0;
                    245: 
                    246:        // 現在の命令先頭アドレスを返す
                    247:        virtual uint32 GetPC() const = 0;
                    248: 
                    249:        // ステップアウトを設定する
                    250:        virtual void SetStepOut() = 0;
                    251:        // ステップアウトなら true を返す
                    252:        virtual bool IsStepOut() const = 0;
                    253: 
                    254:        // name で示されるのレジスタの値を返す。
                    255:        // メモリダンプで指定するケースを想定しているので、明らかにアドレスでは
                    256:        // ないレジスタは含まなくてよい (m680x0 の SR など)。ただし Dn は含めて
                    257:        // よい。また m680x0 の SRP/CRP は下位32ビットでよい。
                    258:        // name が正しくない場合は (uint64)-1 を返す。
                    259:        virtual uint64 GetRegAddr(const char *name) const = 0;
                    260: 
                    261:        // 現在のレジスタセットを内部にバックアップする
                    262:        virtual void BackupRegs() = 0;
                    263: 
1.1.1.2   root      264:        // レジスタ表示系のコマンドを実行。処理すれば true を返す。
                    265:        virtual bool ShowRegister(Console *cons,
                    266:                const std::vector<std::string>& args) = 0;
                    267:        // レジスタ表示系コマンドのヘルプメッセージを取得
                    268:        virtual const HelpMessages& GetRegisterHelp() const = 0;
                    269: 
1.1.1.3 ! root      270:        // ブランチ履歴・例外履歴(オブジェクト)を取得
        !           271:        virtual BranchHistory& GetBrHist() const = 0;
        !           272:        virtual BranchHistory& GetExHist() const = 0;
1.1       root      273: 
                    274:        // 直近の命令でアクセスした laddr が一致したら true を返す
                    275:        // 1 命令で複数にアクセスする場合を考慮して、md 側で判断する
                    276:        virtual bool CheckLEA(uint32 laddr) = 0;
                    277: 
                    278:        // 逆アセンブル。
                    279:        // laddr の位置の命令を一つ逆アセンブルする。
                    280:        // 成功すれば true を返し、失敗すれば(?) false を返す。
                    281:        // 成功した場合 mnemonic に逆アセンブルした文字列が、
                    282:        // bin にこの命令のバイナリ列が格納されている。
                    283:        // mnemonic は単純に命令部分のみ、16進ダンプや付随情報は含まない。
                    284:        // bin はメモリイメージのバイト順で格納すること。
                    285:        virtual bool Disassemble(saddr_t laddr,
                    286:                std::string& mnemonic, std::vector<uint8>& bin) = 0;
                    287: 
                    288:        // 逆アセンブルをフォーマット。
                    289:        // オフライン版は逆アセンブルウィンドウなど、
                    290:        // オンライン版(Live) はデバッガプロンプトで表示するやつ。
                    291:        virtual std::string FormatDisasm(const std::string& mnemonic,
                    292:                const std::vector<uint8>& bin) = 0;
                    293:        virtual std::string FormatDisasmLive(const std::string& mnemonic,
                    294:                const std::vector<uint8>& bin) = 0;
                    295: 
1.1.1.3 ! root      296:        // ベクタ番号の最大値 (+1)
        !           297:        int vector_max = 0;
        !           298:        // 1命令の最小ビット数
        !           299:        uint inst_bits = 0;
        !           300: 
1.1       root      301:  protected:
                    302:        Debugger *parent;               // 親クラス
                    303: };
                    304: 
                    305: #define NORM           "\x1b[0m"
                    306: #define BOLD           "\x1b[1m"
                    307: #define BOLDIF(n)      ((n) ? BOLD : "")

unix.superglobalmegacorp.com

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