おしながき

ELFファイルフォーマット

  • .eh_frameセクションの構造と読み方

DWARFファイルフォーマット

NCURSESライブラリ

  • NCURSES Programing HOWTO ワタクシ的ほんやく
    1. Tools and Widget Libraries
    2. Just For Fun !!!
    3. References
  • その他、自分メモ
  • NCURSES雑多な自分メモ01


最近の更新 (Recent Changes)

2019-09-24
2013-10-10
2013-10-03
2013-10-01
2013-09-29
目次に戻る:DWARFファイルフォーマット

.debug_lineセクションの構造と読み方

.debug_lineセクションって何に使うの?

C言語や他の言語のソースファイルの行と、コンパイルされた機械語コードのアドレスの関係を記録しているみたい。 よーするに、Cソースの12行目の printf("hello"); は、0x80004156バイト目から始まる、call _printf@libc ですよ。みたいなことをつらつらと書いてるらしい。

セクションの構造は?

以下、どっちかというと自分メモ。
Compilation Unit(よーはソースファイル単位)に、以下の構造になってる。

まずヘッダ----------

    • "unit_length"
      • Size: 4 or 8 Byte (32bitDWARFなら4Byte、64bitDWARFなら8Byte)
      • このunit lengthを含まない、Compilation Unit単位の長さらしい
    • "version"
      • Size: uhalf=2Byte(Word)
      • DWARFのバージョンどす。ま、2か3よね。
    • "header_length"
      • Size: 4 or 8 Byte (32bitDWARF=4byte, 64bitDWARF=8Byte)
      • ヘッダの次のバイト(=Cとアセンブラの関係を表す最初のバイト)までの長さ(=ヘッダのサイズ)らしい
    • "minimum_instruction_length"
      • Size: 1 Byte
      • ターゲットマシンで一番小さなマシン語のサイズ。まぁ、x86/64ならNOPが1バイト(90h?)なので、1のはず。(でも、Itaniumならきっと128bit=16なんだろうね。。。使ってみたいなぁ。。)
      • ちなみに、こいつの意味は後述
    • "default_is_stmt"
      • Size: 1 Byte (unsigned)
      • めちゃ簡単にいえば、アセンブラコードの行の解釈の際、原則全てのアセンブラコードの行はBreakpointと対象とするかしないかのフラグ。DWARFは、state machineだから、内部にis_stmtなるレジスタフラグ!をもっていて、こいつがTrueならその時のアセンブラの命令にはBreakpoint仕掛けが可能で、falseならBreakpointはダメよってなる。で、あとで出て来るDW_LNS_negate_stmtなる命令(バイト)によって、このレジスタをXORすることができる仕掛けになってて、Breakpoint仕掛けのOK/NGを制御してるらしい。んで、この値は最初の時点のis_stmtレジスタの値を決めてるってこと。説明がむずい。。。あ、ちなみにstmtはStatementの略?なんかな。。。MK5並にわからんてこの略。マジでキレますよあと5秒で。。。
    • "line_base"
      • Size: 1 Byte (signed!)
      • こいつの意味も、後述。ちなみにsignedがポイント!
    • "line_range"
      • Size: 1 Byte (unsigned)
      • こいつも後述。
    • "opcode_base"
      • Size: 1 Byte (unsigned)
      • この後出て来る、LineNumberProgram の制御命令の一番最初の番号
      • 詳細はこいつも後述
      • DWARF Ver3なら12、DWARF Ver2なら9が通常らしい
    • "standard_opcode_lengths)
      • Size: LEB128 × (opcode_base -1) Byte
      • LNS標準命令の後ろにふっつく引数のByte数を格納した配列らしい
      • 例:opcode_base=3 で、LNS標準命令01h=引数は3Byte、LNS標準命令02h=引数は2Byte なら,"03h,02h"の2Byteらしい
      • LNS標準命令は後程
    • "include_directories"
      • Size: NULL(�)で終る文字列
      • インクルードなファイルのパスを書いてくれてるらしい。
      • stdio.hみたいなコンパイラ標準のincludeはわざわざ書いてくれないみたい。
      • 何個もソース(Compilation Unit)がある場合で、最初の1つに明記されていて、さらに2個目以降のソースも同じ場合は勝手に省略するらしい。。。(要するに、�だけ?)
    • "file_names"
      • このCompilation Unitを構成するソースファイル名の列挙。
      • C言語なら、通常1ソースファイル=1つのCompilation Unitなのだが、世の中のヘンな言語向け機能らしい。(ちなみにDWARFはAdaとかもサポートしてるらしい。てことは、ジャンボジェット君でも何気にDWARFが動いているのかな?)
      • 1つのソースファイルにつき、以下4つの値から構成
          • NULL(�)で終るファイル名の文字列
          • uLEB128 : このソースが格納されているディレクトリを示す、directory index番号
          • uLEB128 : このソースの最終更新日時 (でもどうやって数値で日時表す?utime形式?まさか20111013?)。ちなみに0なら無効(更新日時なんか教えてやるもんか、ってこと)
          • uLEB128 : このソースのサイズ。バイト単位。こいつも0ならサイズなんか教えてやんねーょってことらしい。
      • もうソースファイルねぇよって時は、上記構造のあと0で付いて、STOP!
      • 複数のソースファイルがある場合は、イッコ目から順にファイル番号が1,2,3...って付与される。こいつは、後のLNSプログラム内のファイル番号として参照されるが、断りない限りは1がデフォらしい。
      • directory index番号:
          • directory indexを使う場合は、include_directoriesセクションがELFにできて、このセクションは例によって�切りでソースディレクトリ名が羅列されるみたいっす。
          • この番号=0、は、カレントフォルダがソースディレクトリってこと。(Cは通常0だよねきっと)
          • 1以降はこのセクションから探せってこと。ま、ウォーリー探すよりは楽か。
で、やっとこヘッダが終りーーー。

じゃ、中身も続けよーかと思ったけど、長すぎるから、分割しますた。おヒマな人は、.debug_lineセクションの構造と読み方(中身編)へどーぞ。

目次に戻る:DWARFファイルフォーマット