前回の続き。では、アドレスを探索できる機能を利用して、ブレークポイントの機能を作ってみよう。
gcc+gdbによるプログラムのデバッグ 第2回 変数の監視、バックトレース、その他のコマンド
調査してみると、gdbのブレークポイントは、実行前にブレークが発生するようだ。 つまり、実行時に現在のPCアドレスをブレークポイントリストから探索して、発見すれば命令の実行は中止する。 そして、復帰したときに、当該命令を実行する、という形になる。これは、ちょっと面倒だな... 何故なら、現在のISSはフェッチと実行が同じ関数で実行されるようになっており、フェッチで止めて実行から再開するという機能が備わっていない。 従って、再開時は、ブレークポイントに引っ掛けることなく、再度命令フェッチから開始しなければならない。。。
ExecStatus RiscvEnv::StepExec (bool is_resume_break) { if (IsStopSim() == true) { return ExecStopSim; } SetJumped (false); Word_t inst_hex; int32_t fetch_res; Addr_t fetch_pc = GetPC(); if (FindPCBreak (fetch_pc) && !is_resume_break) { DebugPrint ("<Break PC: %08x>\n", fetch_pc); return ExecBreakPC; } fetch_res = FetchMemory (fetch_pc, &inst_hex); ...
リジューム直後でなく、PCブレークを発見したら、ExecBreakPCを通知して命令の実行を終了する。
mips = make_core ("mips") set_pcbreak (mips, get_addr (mips, "main")) run (mips) print ("PC Break stop.") run (mips)
こうしておけば、main関数に入った時点で一度ストップし、実行を再開する。
29 : [bfc00074] 0000d020 : add r26,r00,r00 r00=>00000000 r00=>00000000 r26<=00000000 30 : [bfc00078] 0000d820 : add r27,r00,r00 r00=>00000000 r00=>00000000 r27<=00000000 31 : [bfc0007c] 0000f020 : add r30,r00,r00 r00=>00000000 r00=>00000000 r30<=00000000 32 : [bfc00080] 0000f820 : add r31,r00,r00 r00=>00000000 r00=>00000000 r31<=00000000 33 : [bfc00084] 3c188000 : lui r24,0x8000 r24<=80000000 34 : [bfc00088] 27182254 : addiu r24,r24,0x2254 r24=>80000000 r24<=80002254 35 : [bfc0008c] 0300f809 : jalr r24,r31 r24=>80002254 r31<=bfc00094 pc<=bfc00090 pc<=80002254 36 : [bfc00090] 00000000 : sll r00,r00,0x00 r00=>00000000 <Break PC: 80002254> <Run: MIPS> <Func: main> 37 : [80002254] 27bdff70 : addiu r29,r29,0xff70 r29=>7f004008 r29<=7f003f78 38 : [80002258] 27a50058 : addiu r05,r29,0x0058 r29=>7f003f78 r05<=7f003fd0 39 : [8000225c] 27a60054 : addiu r06,r29,0x0054 r29=>7f003f78 r06<=7f003fcc 40 : [80002260] 27a40052 : addiu r04,r29,0x0052 r29=>7f003f78 r04<=7f003fca 41 : [80002264] afbf008c : sw r31,0x008c(r31) r29=>7f003f78 r31=>bfc00094 (7f004004)<=bfc00094 42 : [80002268] afbe0088 : sw r30,0x0088(r30) r29=>7f003f78 r30=>00000000 (7f004000)<=00000000
うん、いい感じだ。