• Showing Page History #88965
目次に戻る:DWARFファイルフォーマット

.debug_locセクションの構造(LocationLists)

(2013/05/28 書き始めたのよ〜まだ見ても中身ないもん)

.debug_locセクション(Location Lists)って何?

Location Listsは、前のページで触れましたが、Location Descriptionの2つの表現方法のうちのもう1つで、「プログラムの開始から終了までの期間(ライフタイム)で、格納場所がころころ変わったり、プログラムの開始から終了の間の一時期しか存在しないやつ、の格納場所を表現する方法」みたいです。
んで、この情報は、前ページのLocation expressionsとは異なり、専用のELFセクション、.debug_locセクションに格納される仕様になってます。(セクション持ちってことで、凄いヤツなのかしらといったところです)
でも、独立したセクション持ってるってことは。。。また解析が必要っすね。ということで、以下またメモです。


.debug_locセクションのデータ構造

.debug_locセクションは、データの形式的には、以下のデータ構造がひたすら連続してつまってます。

<開始オフセットアドレス> <終了オフセットアドレス> <Location expression>

ただし、その意味の解釈の仕方で、以下の3パターンがあり、それぞれで上記3つのデータ項目の意味が違ったり、値が固定だったり、はたまたデータ項目がなかったり、します。
つーことで、まず以下に3種類のデータ解釈方法です。(それぞれの意味は以下それぞれの節みてね)

No. 解釈パターンの名前(エントリ名) エントリの概要 <開始オフセットアドレス> <終了オフセットアドレス> <Location Expression>
1 Location List Entry (LLE) 生存範囲が限定されている格納場所の情報示すオブジェクト(値とか)の生存範囲とその範囲内での格納場所を示すレコード。 生存範囲の
開始オフセット
生存範囲の
終了オフセット
指定された範囲での
格納場所を示す
Location Expression
2 Base Address
Selection Entry (BASE)
上記No.1 Location List Entryでの開始/終了オフセットのベースアドレスを指定するレコード 0xffffffffffffffff (64bit)
0xffffffff (32bit)
ベースアドレス なし
(このデータは持たない)
3 End of List Entry (ELE) 表現対象のオブジェクトに対する全てのNo.1 Location List Entryが終ったことを示すレコード 0x00 0x00 なし
(このデータは持たない)


んで、これらのパターンの使われ方としては、例えば

  • あるデータAとBがあったとする
  • データAは
    • プログラムカウンタがアドレス1からアドレス3までの範囲にあるとき、場所xに格納されている
    • プログラムカウンタがアドレス5からアドレス7までの範囲にあるとき、場所yに格納されている
  • データBは、
    • (仮定だが、何らかの理由によって)アドレス2000からアドレス2010までの範囲にあるとき、場所zに格納されている

みたいなケースがあったとき、

<LLE(1,3,x)> <LLE(5,7,y)> <ELE(0,0,-)> <BASE(0xffffffff,2000,-)> <LLE(0,10,z)> <ELE(0,0,-)>
※LLEはパターン1 Location List Entryのこと、 BASEはパターン2 Base Address Selection Entryのこと、 ELEはパターン3 End of List Entryのこと。(カッコ)内は、それぞれ(開始オフセット、終了オフセット、Location Expression)を示す

の様に表現されるみたいです。
あと、".debug_locセクション"内には、例えば上の例ではじめの2つのLLEが「データA」のことである、という情報は持っていません。これは.debug_infoで持っていて、".debug_locセクション"は".debug_infoセクション"の該当するデータを指し示すDIEから、指さされる、といった具合です。


Location List Entryのせつめい

(上の例である意味説明できているのでいまさら感ありですが。。。)
このエントリでは、あるデータ(オブジェクト)が、プログラムコードアドレスの場所(範囲)によって、メモリにある、レジスタにある、などの場合、「どのプログラムコードアドレスの範囲を実行中は、対象のデータはどこに格納されているか」を示すレコードです。
当然、あるデータがプログラムコードアドレスの範囲3箇所で、それぞれ別の場所に格納される、という場合は、このレコードは3つできます。そして、通常アドレス範囲が若い方から格納されます。
ということで、まず引数です。

引数名 サイズ 形式 せつめい
生存範囲の開始オフセット 実行マシンのアドレスサイズ?
(32bit=4byte, 64bit=8Byte)
★要調査★
アドレス値 対象とするデータの、引数3のLocation Expressionの場所に格納されている期間の、開始アドレスオフセットです。
開始アドレスは、プログラムコードアドレスのオフセットで、これは通常はこのデータのCompailation Unit、よーは定義されているソースファイルのプログラムコード開始アドレスからの差分値です。
(但し、このレコードから、レコードを前に遡っていき、ELEが登場するまでの間にBASE(Base Address Selection Entry)が登場しない場合。BASEがある場合は、BASEで指定されたアドレスからのオフセット値になりますとーぜん)
生存範囲の終了オフセット 実行マシンのアドレスサイズ?
(32bit=4byte, 64bit=8Byte)
★要調査★
アドレス値 対象とするデータの、引数3のLocation Expressionの場所に格納されている期間の、終了アドレスオフセットです。
終了アドレスオフセットは、プログラムコードアドレスにおける引数3のLocation Expressionで場所表現できる範囲の最後のアドレスになりますです。
この値はオフセットですが、そのベースとするアドレスの考え方は、生存範囲の開始オフセット、と同じ考え方です。
なお、「開始オフセット」=「終了オフセット」の場合、そのLLEは意味を持たないもの、となります。(範囲がなくなっちゃうので、あるいみとーぜんです)
Location Expression
(★要調査★)
BLOCK?
(長さのuLEB128+指定された長さのバイナリ?)
「開始オフセット」〜「終了オフセット」で指定された範囲内における、対象データの格納場所を示すLocation Expressionです。
Location Expression の解析方法は、前ページを見てね。
あとこれ、不明点があって、どこかにデータ長を示す項目が必要なはずですが、見当たらない。Location Expressionは先の通り、DWARF expression表現形式なので、サイズが不定です。
多分、これはこの引数の値に、続くLocation Expressionのデータ長を指定するuLEB128があって、その後データが続いているものと思われます


Base Address Selection Entryのせつめい

このエントリは、前のLocation List Entryの引数である、開始アドレスオフセット、終了アドレスオフセットから実際の開始アドレス、終了アドレスを計算する際の、ベースアドレスを.debug_infoセクションのCompilation Unit(ソースファイル)の開始アドレス、じゃない値とする場合に 使われるエントリです。
要は、強制的に開始/終了アドレスオフセットのベースアドレスを書き換えます。
役割自体は、これだけなんですが、以下数点、注意っす。

  • (そのプログラムの)全てのマシンコードが1つの、連続したセクションに配置されるCompilatin Unit(ソースファイル)の場合、このセクションは不要。 (=通常、登場しない)
  • (このエントリを使うことによって) あるデータの生存期間が重複してしまうことがあり、この時、あるデータの生存期間の範囲として指定された、全ての範囲を合算した際、穴のあく範囲が現れることがある
    • この穴となった範囲では、対象とするデータは存在しない、と考える必要があります。
  • このエントリで指定したベースアドレスの有効範囲は、このエントリ発行した時点、から、最初のELEまで、です。


では、このエントリの引数です。

引数名 サイズ 形式 せつめい
開始アドレスオフセット 4Byte(32bit)
8Byte(64bit)
マシンのアドレスサイズ依存
固定値(参照→) この引数は、BASEであることの「区別」のみに使われます。
区別の仕方は、この値が0xffffffff (32bitアドレス時)、0xffffffffffffffff (64bitアドレス時)ならBASEです。
(なお、0x00ならELE、それ以外ならLLEです)
終了アドレスオフセット 4Byte(32bit)
8Byte(64bit)
マシンアドレスサイズ依存
アドレス値 この引数に、書き換えるベースアドレス値が格納されています

※Location Expression(引数3)は、ありません。(すぐに次のエントリにいきます)


End of List Entryのせつめい

格納場所を示すために必要なLLEを全部書き切ったら、最後にSTOP!の意味としてこの"End of List Entry"が必要です。
引数は、以下です。

引数名 サイズ 形式 せつめい
開始アドレスオフセット 4Byte(32bit)
8Byte(64bit)
マシンのアドレスサイズ依存
固定値(参照→) 0x00固定です。
また、この値が0x00ならELE、と判断するのにも使います
終了アドレスオフセット 4Byte(32bit)
8Byte(64bit)
マシンアドレスサイズ依存
固定値(参照→) 0x00固定です。

※Location Expression(引数3)は、ありません。(すぐに次のエントリにいきます)

この命令のあと、次なる表現対象のデータがあれば、そのデータのLLEかBASEが続きます。この命令のデータバイトが.debug_locセクションの最後のバイトであれば、それでこのセクションのデータは終りです。
なお、BASE/ELEは、".debug_rangeセクション"の「Base Address Section Entry」「End of List Entry」と等しくなるそうです。
(という、まだ分かっていない記述が原文にあります。ので、次は.debug_rangeセクションの解析を予定です。 2013/05/29)


実機での解析例

(2013/05/29 まだ作成中なのよねぇ〜)


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