えと、.debug_frameな話は、まだ規格書(DWARF V3)を読んだだけで、実機での確認してません! よーは、えーかげんってことです!
.debug_lineもまだ怪しい多数ですが、それ以上に信じないでね。(2013/4/22現在)
間違い指摘は歓迎っす!(どのみち、このあとプログラム書いてバグではまるだけなので。。。)
.debug_frameセクションには、Call Frameの情報が格納されている。
Call Frameって? えと、C言語(というか、多分ほかの言語のほとんども)では関数呼び出した時、スタックに戻り先のアドレスやら自動変数やらをつっこむわけですが、このときのスタックの構造って、通常どう突っ込むか、決まってます。
んで、呼び出すたびに毎回同じつっこみ方の構造をスタックに作るので、このつっこみ方の構造=Call Frameなのです。
よーは、このセクションを解読すると、多分以下のことが分かります。
これ分かることで、今実行中の関数、はどいつが、どっから呼ばれたが分かるのです!これはデバッガでは重要ですね。
ということで、約1年版振りに本業が落ち着いたので、解読再開!
えと、これ難しいっす! (ワタクシの英語力が足りなさすぎるというツッコミもありですがね。。。)
ヘッダとはうんちゃら構造の説明の前に、まずデータの持ち方の考え方から。これが面倒
アドレス | CFA | Reg0 | Reg1 | ... | RegX |
addr 0 | CFA 0 | Reg0値0 | Reg1値1 | ... | RegX 値1 |
addr 1 | CFA 1 | Reg0値1 | Reg1値2 | ... | RegX 値2 |
addr 2 | CFA 2 | Reg0値2 | Reg1値3 | ... | RegX 値3 |
addr 3 | CFA 3 | Reg0値3 | Reg1値4 | ... | RegX 値 4 |
まず、仮想的にこーいう表があるとします。(これを Call Frame Information: CFI と呼びますらしいです)。
んで、1行はアセンブラの命令1つ、の単位。列のそれぞれの意味は
例えば、仮想のReg7+0のアドレスがCFAなら、"Reg7+0"が書き込まれる。この計算ルールの表現方法は後述です。(2013/05/05 誤り訂正)
んで、この勝手に作ったレジスタは、CPUのホンモノレジスタとおんなじモノと割り当てる、とか、の設定ができます。
で、最後に表の行、すなわち、命令実行していくなかでそれぞれのレジスタがどう変化していくか、値はどこにあるのか、を命令毎に一行づつ、示して行くようになっています。
この表の例は、まぁDWARF V3のappendix D.6の例を見た方が分かりやすいので、こんなん知りたいってヒトはそっち見てくださいです。
あ、ちなみにこの例のアセンブラ(motorola 88000)の命令文体系、ちとヘンです。以下オトシアナ(規格を和訳)
ってあります。これ、このこのまま読むと
の例なら、R1にR7+8の値を突っ込む、intel形式なら、 ”mov r1, dword ptr r7+8”になる、と誰もが読むはずですが。。。。ブッブー!
正しくは、上の例は、R7+8のアドレスに、R1を突っ込む、すなわちintel君語なら”mov dword ptr R7+8, R1”になります!
でも、loadは、”load R1, R7, 8”の場合、intel語では”mov r1, dword ptr R7+8”になります。
うーん、僕がintel語に毒されているのか。。。m88000がヘンなのか?
識者のみなさま、RISCってこんなもんですかね?使ったことないんで分からんのですが。。。。
CFI内でのCFA、Reg(仮想レジスタ)の表現方法は、.debug_line同様、またまたバイト/ビットの世界でのエンコードで表現されちゃいます。
これらの、命令と具体的な意味は後述ですが、ここではその説明の際の「ルール」なるものを書きます。
これ、頭っから読んでくれている方は、この段階では「ふーん」だけにしときましょう。考えればこんがらがること、必定です!
以下8種類あります。
前置きはこん位として、実際の.debug_frameのデータ構造です。これは、以下の2つのデータ構造が、ひたすら並んでる、だけです。(と思われます。 2013/5/5現在)
(2013/5/8 以下大嘘(誤解)が判明。取消です)
ここで意識しておきたいのは、以下の点。(C言語の場合) すなわち、CIE1つとそれにヒモ付くFDE複数個、のセットで1つの関数を表すってこと。
1つの関数=1つのCIE、という形になる。(これはとーぜんで、関数1つを呼び出す際のABIのパターンは当然1つだから。また、関数(の引数などの条件)によってアセンブラレベルの呼び出し方、すなわちCFAの持ち方が変わるのは当然だから)
いずれにしても、CIE、FDEのデータの持ち方、はx86-64でちゃんと調べる必要があり、つもりです。
そして、データの格納構造としては、以下の様な感じでひたすら、連続してつめこまれています。(ただし、アドレスのバウンダリは意識され、余った分には0がパディング?)
なお、CIE/FDEのヘッダは、どちらも最初の4バイトはその後のその構造のデータサイズ、次の8バイト(64bitの場合、32bitなら4byte)の値までは構造が同じになっていて、2つめの項目の値が-1かどうかで、CIEかFDEかを見分けます。
ということで、この後はCIE/FDEを見て行きますです。
目次に戻る:DWARFファイルフォーマット
[PageInfo]
LastUpdate: 2013-05-28 22:09:58, ModifiedBy: koinec
[License]
FreeBSD Documentation License
[Permissions]
view:all, edit:members, delete/config:members