3

コンパイルされたcプログラムからグローバル変数を抽出する必要があります。私が今していることは、その情報を取得するためにLinuxreadelfコマンドを使用することです。言い換えれば、私がするとき:

  readelf.exe -w[i]  myFile.out      

ここreadelf.exeからダウンロードできるプログラムでそれを行います。私はウィンドウを使用していて、それが私が必要とする唯一のコマンドだからです。Linuxでは、コンソールを開いて実行しますreadelf -w[i] myFile.out

とにかく、そのコマンドを実行すると、次のようになります。

 <1><86923>: Abbrev Number: 2 (DW_TAG_base_type)
    <86924>   DW_AT_name        : unsigned int  
    <86925>   DW_AT_encoding    : 7 (unsigned)
    <86927>   DW_AT_byte_size   : 4 
<1>..
...
... bla bla bla
... 
<1><870a1>: Abbrev Number: 12 (DW_TAG_variable)
    <870a2>   DW_AT_decl_file   : 25    
    <870a3>   DW_AT_decl_line   : 543   
    <870a5>   DW_AT_external    : 1 
    <870a6>   DW_AT_name        : NetBuf_ID_Ctr     // <------------------- First variable
    <870b4>   DW_AT_type        : <0x86923> 
    <870b8>   DW_AT_location    : 5 byte block: 3 ff f9 b 20    (DW_OP_addr: fff90b20)
 <1><870be>: Abbrev Number: 3 (DW_TAG_typedef)
    <870bf>   DW_AT_decl_file   : 26    
    <870c0>   DW_AT_decl_line   : 192   
    <870c2>   DW_AT_name        : NET_CONN_FAMILY   
    <870d2>   DW_AT_type        : <0x862f1> 
 <1><870d6>: Abbrev Number: 3 (DW_TAG_typedef)
    <870d7>   DW_AT_decl_file   : 26    
 ....

その「ツリー」を使用して、すべてのグローバル変数とタイプを取得できます。たとえば、最初の変数NetBuf_ID_Ctrを見ると、ノードの型に関する情報を取得できることがわかります <0x86923>。そのノードはツリーのどこかにあります!実際に最初のノードであるものを見てください。開始するもので <1><86923>....、そのノードの内部を見ると、変数が4バイトのサイズのunsignedintであることがわかります。


今私の質問は、そのreadelfコマンドを使用すると ここに画像の説明を入力してください 、解析する必要のある192883行のテキストを取得することです。このツリーは、私が必要としているものよりも多くの情報を私に与えてくれます。16進エディタでファイルを調べると、次のように表示されます。

ここに画像の説明を入力してください

同じ変数を見つけることができ、そのNetBuf_ID_Ctr隣(強調表示)はアドレス<0x86923>です!

木の作り方を教えてくれる場所はインターネット上にありますか?コマンドreadelf.exeは、ツリーを作成するのに.1秒かかります。出力をStreamReaderに配置するため、非常に高速です。そのStreamReaderをメモリに配置して、非常に時間がかかる文字列に変換したい場合。


編集

要約すると、myFile.outからツリー(readelfの出力)がどのように構築されているかを知りたいと思います。そのパターンを理解することも、インターネット上のその方法を説明する場所もわかりません。

4

1 に答える 1

1

基本的に、ELF オブジェクト ファイル内の dwarf デバッグ情報はセクションに存在します。

  • .debug_aranges
  • .debug_frame
  • 。デバッグ情報
  • .debug_line
  • .debug_pubnames
  • .debug_pubtypes

ダイのツリーは、デバッグ情報エントリ (DIE) 間の関係を記述する .debug_info 内の情報を解析することによって構築されます。この情報がどのように保存されるかは、ここにある DWARF 標準で説明されています。

あなたの質問から、すべてのグローバルシンボルをできるだけ早くダンプしたいようです。独自のプログラムからこれを行いたい場合は、libdwarf を使用して .debug_pubnamesの内容を解析できます。このセクションには、いくつかの名前とオフセットのペアが続く一連のヘッダーが含まれます。名前はグローバル名であり、オフセットはコンパイル単位の開始からの DIE のオフセットです。これは、libdwarf がより詳細な情報を取得するために再び使用できます。

libdwarf は Windows 上で非常に簡単にコンパイルできますが、libelf も必要になります。DWARF Debug Information Format の簡単な説明については、こちらも参照してください。

于 2012-07-11T20:19:26.213 に答える