おしながき

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_rangesセクションの構造(CodeAddress&Range)

Code Address & Rangesって?

.debug_rangeセクションの構造、の前に、まず前提として、これです。
DWARFの.debug_infoセクション内の各レコード(DIE)内では、Compilation Unit(C言語なら、.cソースファイルの単位)とか、モジュールの初期化時、関数、通常のプログラムブロック、(C++の)try/catchブロック、ラベルなどのデバッグ情報の一部として、プログラムコードのアドレスや、アドレスの範囲が指定されることがありますです。
んで、これらの情報は、.debug_info/.debug_abbrev内の属性では、以下のものにそーとーするみたいです。(これ、後の.debug_infoのとこのメモで、イヤというほど出てきそうです。今は、へぇーでいいような)

  • DW_AT_low_pc
    • 1つのプログラムコードアドレスを示す時の属性 (DWARFではこいつを、Single Addressっていってます)
    • .debug_info内では、ラベルやサブプログラムの別のエントリポイントを示す際に使われるっぽい。って、サブプログラムってのは、何?
    • DW_AT_low_pcの属性値として、「再配置された後のアドレス」も持っています。(よーは、実際にメモリ展開された時のアドレスってこと)
  • DW_AT_low_pc & DW_AT_high_pcの組
    • 1つの連続したプログラムコードアドレスの範囲を示す。(これを Contiguous Address Rangeっていう。で、この範囲内の領域のデータは、全て表示対象とするプログラムコードとなります=途中に、穴があくことはないですってことです)
    • これは、例えばこの関数のプログラムコードアドレスの範囲は0x00100〜0x00200まで、みたいなやつ
    • DW_AT_low_pcの属性値は、プログラムコードアドレス範囲の最初の命令のあるアドレス
    • DW_AT_high_pcの属性値は、指定したいプログラムコードアドレスの「次の命令のあるアドレス」 (すなわち、このアドレス未満ってこと)
  • DW_AT_ranges : 連続していないプログラムコードアドレス
    • 例えば、0x0100〜0x0130と、0x0150〜0x0200の2箇所、みたいな指定のやつ。
    • これを、"Non-contiguous Address Ranges"って名付けたみたいです。
    • このケースにおけるプログラムコードアドレス範囲(複数ある)は、Range Listsと称して、.debug_rangeセクションに格納されてるです。
    • DW_AT_rangesの属性値は、rangelistptrクラスのデータで、この時のプログラムコードアドレスの範囲が書かれている、.debug_rangeセクションの冒頭からのオフセット値が格納されています。


.debug_rangeセクションの構造

ということで、.debug_rangeセクションの目的が分かったところで、構造です。
で、上のメモから、このセクションでは、連続しない複数箇所の範囲、を表現するためのもんです。これって言い替えると、開始アドレスと終了アドレスの組、が複数あれば、表現できますすよね。
そして、この構造どっかで見たような。。。どうも、.debug_locと、目的違えど、構造ってほとんど同じっぽいです。
てなわけで、まずデータ格納構造です。以下のデータの組が、ひたすら連続してつまっている、です。

<開始オフセット> <終了オフセット>
※.debug_locとの決定的な違いは、3つめがありません。。今回は、開始と終了だけです。(だから、もっと簡単)


で、例によって、この組で表現されるデータの種類が、以下の3種類があります。

No. データ構造名 <開始オフセット> <終了オフセット> 簡単なせつめい
1 Range List Entry (RLE) プログラムコードアドレス範囲の
開始アドレスオフセット
マシンのビットサイズ
プログラムコードアドレス範囲の
終了アドレスオフセット
マシンのビットサイズ
プログラムコードアドレスの範囲の1つ、を示すレコードです
2 Base Address Selection Entry
(BASE)
0xffffffffffffffff (64bit)
0xffffffff (32bit)
ベースアドレス
マシンのビットサイズ
RLEのオフセットのベースとなるアドレス、を指定するレコード
3 End of List Entry (ELE) 0x00
マシンのビットサイズ
0x00
マシンのビットサイズ
対象としていた"Non-contiguous Address Ranges"の終了を示すレコード


なので、例えば、"Non-contiguous Address Ranges"で表現する対象のプログラムコードアドレスが2つあり(AとBとする)、それぞれ3つずつのアドレス範囲から構成されていて、Bはベースアドレスの設定が必要、と言うケースでは、

(RLE A-1) (RLE A-2) (RLE A-3) (ELE) (RLE B-1) (BASE B) (RLE B-2) (RLE B-3) (ELE)

みたいない、データ構造になる、ってことです。


Range List Entry (RLE)の補足

RLEでの<開始オフセット>、<終了オフセット>は、文字づらの通り、「オフセット」です。つまりどっかのアドレスからの、相対アドレスってことです。
では、どっから?ってなりますね。これ、以下のルールで決まります。

  • 今見ているRLEが含まれる"Non-contiguous Address Ranges"のRange List内にBASEがある場合:
    • ※「今参照しているRLEより前のデータを遡って見ていった時で、かつELEが出現するまでの範囲に、BASEがある場合」と言う意味です。
    • そのBASEで指定しているベースアドレスからのオフセット、になります。
    • 上の例で、今(RLE B-3)を見ているなら、その2つ前に(BASE B)がいますので、このベースアドレスからの相対になります。
  • 今見ているRLEが含まれる"Non-contiguous Address Ranges"内に、BASEがいない場合:
    • このRange List("Non-contiguous Address Ranges")を参照している、.debug_info側のエントリを抱えているCompilation Unitのベースアドレスからのオフセットです。
      .debug_infoのCompilation Unit Header内に、DW_AT_low_pcがいますので、この属性値からのオフセットです(C言語の場合)
    • 上記例で、今(RLE B-1)なら、その前にBASEはいないので、Range List Bを参照しているCソースのプログラムコードアドレスの先頭から、ってことです。


また、<終了オフセット> ≧ <開始オフセット> が成立します。(つーか、しないと訳分かんなくなるんで、とーぜんですけどね)


Base Address Selection Entryの補足

  • BASEが登場した場合の効力の範囲は、登場した時点から、そのBASEが所属する"Non-contiguous Address Ranges"のELE(よーするに、次のELE)までの間です。
  • Range Listで表現するプログラムコードアドレスの範囲が、1つのELFセクション内にある場合は、通常このBASEは登場しませんです。


実機での解析

ほな、いきまひょか〜としたいのですが。。。これも、どーやっても、実機でこのセクションをつくり出せてないです。(.debug_pubtypesとおんなじ)

ので、スミマセンが、今回は実機解析できまへぇんーーーー。
まぁ、ただ幸い、構造が簡単なことと、.debug_locと似通っていてそっち見れば分かる、というのがあるんで、割愛です。


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