bfdのシンボルには、BSF_GLOBALとBSF_LOCALという、変数やセクション、各種定数を格納するためのセクションがある。 この中で、BSF_GLOBALはグローバル変数の情報が格納されており、取り扱うには一番簡単っぽいので試してみた。
関数のシンボルテーブルを作成したときと同じように、bfdからシンボル一覧をロードして、std::vectorに格納しておく。
void EnvBase::LoadGVariableTable (bfd *abfd) { long storage_needed; asymbol **symbol_table; long number_of_symbols; storage_needed = bfd_get_symtab_upper_bound (abfd); if (storage_needed < 0) { std::cerr << "Error storage_needed < 0\n"; exit (EXIT_FAILURE); } if (storage_needed == 0) { std::cerr << "Error storage_needed == 0\n"; exit (EXIT_FAILURE); } symbol_table = (asymbol **) malloc (storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) { std::cerr << "Error: number_of_symbols < 0\n"; exit (EXIT_FAILURE); } 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 "); } else if ((symbol_table[i]->flags & BSF_LOCAL) != 0x00) { // fprintf (stdout, "BSF_Local %s %08x\n", } else if ((symbol_table[i]->flags & BSF_GLOBAL) != 0x00) { // fprintf (stdout, "BSF_Global %s %08x\n", // bfd_asymbol_name(symbol_table[i]), // bfd_asymbol_value (symbol_table[i])); FunctionInfo *p_gvar_info = new FunctionInfo (); p_gvar_info->symbol = bfd_asymbol_name(symbol_table[i]); p_gvar_info->addr = bfd_asymbol_value (symbol_table[i]); // Insert new function table m_gvar_table->push_back (p_gvar_info); } else { // fprintf (stdout, "BSF_others "); } } DebugPrint ("<Finish loading global variable table>\n"); }
m_gvar_tableにグローバル変数とそのアドレス情報をペアで格納しておき、メモリアクセスが発生したときに探索する。
ロード命令の場合は以下だ。FindGVariable関数を実装しておき、ヒットすると、デバッグ情報を表示する。
/*! * Load Data from Memory */ MemResult EnvBase::LoadMemory (Addr_t addr, Size_t size, Word_t *data) { MemResult res; switch (size) { case Size_Byte: { Byte_t byte; res = LoadMemByte (addr, &byte); *data = static_cast<Word_t>(byte); m_trace->RecordTraceMemRead (addr, *data, size); break; } case Size_HWord: { HWord_t hword; res = LoadMemHWord (addr, &hword); *data = static_cast<Word_t>(hword); m_trace->RecordTraceMemRead (addr, *data, size); break; } case Size_Word: res = LoadMemWord (addr, data); m_trace->RecordTraceMemRead (addr, *data, size); break; default: fprintf (m_dbgfp, "<Internal Error: Illegal size of LoadMemory : %d>\n", size); exit (EXIT_FAILURE); break; } std::string gvar_symbol; if (IsDebugGVar () && (FindGVariable (addr, &gvar_symbol) == true)) { DebugPrint ("<GlobalVar: %s=>%08x>\n", gvar_symbol.c_str(), *data); } return res; }
これらを利用するためには、--debug_gvarオプションを利用するか、Luaインタフェースからは、debug("gvar")を追記しておくことで利用できる。 下記のように、関数のジャンプ情報と、グローバル変数のアクセス情報を表示できるようになった。
78 : [800016c0] 00f50533 : add r10,r10,r15 r10=>00000008 r15=>80002aa0 r10<=80002aa8 79 : [800016c4] 00052783 : lw r15,r10,0x000 r10=>80002aa8 (80002aa8)=>800016dc r15<=800016dc 80 : [800016c8] 00078067 : jalr r00,r15,r103 r15=>800016dc pc<=800016dc <GlobalVar: seed2_volatile=>00000000> 81 : [800016dc] 7e41a503 : lw r10,r03,0x7e4 r03=>7f000010 (7f0007f4)=>00000000 r10<=00000000 82 : [800016e0] 00008067 : jalr r00,r01,r103 r01=>80002348 pc<=80002348 83 : [80002348] 00a11723 : sh r02,r10,0x00|r14 r02=>7f003f78 r10=>00000000 (7f003f86)<=00000000 84 : [8000234c] 00300513 : addi r10,r00,0x003 r00=>00000000 r10<=00000003 85 : [80002350] b5cff0ef : jal r01,0xb5cff r01<=80002354 pc<=800016ac <Func: get_seed_32> 86 : [800016ac] 00500793 : addi r15,r00,0x005 r00=>00000000 r15<=00000005 87 : [800016b0] 04a7e263 : bltu r15,r10,0x02 r15=>00000005 r10=>00000003 88 : [800016b4] 800037b7 : lui r15,0x80003 r15<=80003000 89 : [800016b8] aa078793 : addi r15,r15,0xaa0 r15=>80003000 r15<=80002aa0 90 : [800016bc] 00251513 : slli r10,r10,r02 r10=>00000003 r10<=0000000c 91 : [800016c0] 00f50533 : add r10,r10,r15 r10=>0000000c r15=>80002aa0 r10<=80002aac 92 : [800016c4] 00052783 : lw r15,r10,0x000 r10=>80002aac (80002aac)=>800016e4 r15<=800016e4 93 : [800016c8] 00078067 : jalr r00,r15,r103 r15=>800016e4 pc<=800016e4 <GlobalVar: seed3_volatile=>00000066> 94 : [800016e4] 0041a503 : lw r10,r03,0x004 r03=>7f000010 (7f000014)=>00000066 r10<=00000066 95 : [800016e8] 00008067 : jalr r00,r01,r103 r01=>80002354 pc<=80002354 96 : [80002354] 00a11823 : sh r02,r10,0x00|r16 r02=>7f003f78 r10=>00000066 (7f003f88)<=00000066 97 : [80002358] 00400513 : addi r10,r00,0x004 r00=>00000000 r10<=00000004 98 : [8000235c] b50ff0ef : jal r01,0xb50ff r01<=80002360 pc<=800016ac <Func: get_seed_32> 99 : [800016ac] 00500793 : addi r15,r00,0x005 r00=>00000000 r15<=00000005 100 : [800016b0] 04a7e263 : bltu r15,r10,0x02 r15=>00000005 r10=>00000004