FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

シミュレーションログに関数名を表示させる

Bfd, Luaといろいろ道具は揃ってきたので、いろんな便利機能を実装してみよう。

github.com

まずは、関数の先頭にジャンプしたときに、その関数名を表示するように変更する。 この機能は、Lua側からだと、debug("func")を追加するか、 引数だと、--debug_func で有効にできる。

./swimmer_riscv --max 1000000 --out debug.log --binfile ~/benchmarks/coremark_v1.0/coremark.bin --script init.lua  --debug_func
...
        31 : [0000017c] 00000f33 : add        r30,r00,r00          r00=>00000000 r00=>00000000 r30<=00000000
        32 : [00000180] 00000fb3 : add        r31,r00,r00          r00=>00000000 r00=>00000000 r31<=00000000
        33 : [00000184] 80002417 : auipc      r08,0x80002          r08<=80002184
        34 : [00000188] 16440413 : addi       r08,r08,0x164        r08=>80002184 r08<=800022e8
        35 : [0000018c] 000400e7 : jalr       r01,r08,r231         r08=>800022e8 r01<=00000190 pc<=800022e8
<Func: main>
        36 : [800022e8] f7010113 : addi       r02,r02,0xf70        r02=>7f004008 r02<=7f003f78
        37 : [800022ec] 00810613 : addi       r12,r02,0x008        r02=>7f003f78 r12<=7f003f80
        38 : [800022f0] 00410593 : addi       r11,r02,0x004        r02=>7f003f78 r11<=7f003f7c
        39 : [800022f4] 04e10513 : addi       r10,r02,0x04e        r02=>7f003f78 r10<=7f003fc6
        40 : [800022f8] 08112623 : sw         r02,r01,0x04|r12     r02=>7f003f78 r01=>00000190 (7f004004)<=00000190
        41 : [800022fc] 08812423 : sw         r02,r08,0x04|r08     r02=>7f003f78 r08=>800022e8 (7f004000)<=800022e8
        42 : [80002300] 08912223 : sw         r02,r09,0x04|r04     r02=>7f003f78 r09=>00000000 (7f003ffc)<=00000000
        43 : [80002304] 09212023 : sw         r02,r18,0x04|r00     r02=>7f003f78 r18=>00000000 (7f003ff8)<=00000000
        44 : [80002308] 07312e23 : sw         r02,r19,0x03|r28     r02=>7f003f78 r19=>00000000 (7f003ff4)<=00000000
        45 : [8000230c] 07412c23 : sw         r02,r20,0x03|r24     r02=>7f003f78 r20=>00000000 (7f003ff0)<=00000000
        46 : [80002310] 07512a23 : sw         r02,r21,0x03|r20     r02=>7f003f78 r21=>00000000 (7f003fec)<=00000000
...

こんな感じで、関数の先頭にジャンプしたときに、関数の名前を表示するようにする。

これを実装するために、Bfdでバイナリをロードするときに、関数のシンボル名とアドレスのペアをベクタとして格納しておいた。

    for (int i = 0; i < number_of_symbols; i++) {

        // fprintf (stdout, "SymbolName=%s : ", bfd_asymbol_name (symbol_table[i]));
        if ((symbol_table[i]->flags & BSF_FUNCTION) != 0x00) {
            // fprintf (stdout, "BSF_Function ");
            FunctionInfo *p_func_info = new FunctionInfo ();
            p_func_info->symbol = bfd_asymbol_name(symbol_table[i]);
            p_func_info->addr   = bfd_asymbol_value (symbol_table[i]);
            // Insert new function table
            m_func_table->push_back (p_func_info);
...

こんな感じで、bfdから情報を取り出して、envのメンバ変数であるm_func_table(関数名とアドレスのペアがベクタになって格納されている)に格納しておき、フェッチする度にサーチする、という形式にした。

    fetch_res = FetchMemory (fetch_pc, &inst_hex);

    if (fetch_res == -1) {
        GenerateException (Except_InstAddrMisalign);
        return;
    }

    std::string func_symbol;
    if ((IsDebugFunc () == true) &&
        (FindSymbol (fetch_pc, &func_symbol) == true)) {
        DebugPrint ("<Func: %s>\n", func_symbol.c_str());
    }

FindSymbolで関数名にヒットすれば、そこで情報を表示する。

bool EnvBase::FindSymbol (Addr_t addr, std::string *symbol)
{
    FunctionTable::iterator it = m_func_table->begin ();
    while (it != m_func_table->end ()) {
        Addr_t symbol_addr = (*it)->addr;
        if (symbol_addr == addr) {
            *symbol = (*it)->symbol;
            return true;
        }
        it++;
    }
    return false;
}