おしながき

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ファイルフォーマット

TAG詳細(その13) 関数/クラス/構造体へのポインタ編

このページでは、C言語/C++固有、と言うわけではないですが、C/C++に強く依存?しているポインタ(関数ポインタ含む)についてかきます。


関数型 (関数へのポインタ)

C言語での「関数へのポインタ」を使うことができます。で、これは関数への「ポインタ」ですでの、TAG詳細(その08)の型修飾子に書いた、ポインタ指定を行うことにとなるわけですが、もしそうだとすると修飾される「関数型」ってのが必要になります。
で、DWARFではその通り、「関数型」って基本型を設けています。以下、その説明です。

  • 「関数型」は、「DW_TAG_subroutine_type」なTAGのDIEで表現するとのお達しです。
  • このTAG、Attributeとしては以下を持っています。
    No. Attribute名 せつめい
    1 DW_AT_name (ソース上で関数型に名前が与えられている場合)
    ソース上の関数型の名称がはいる(NULL終り文字列)
    ※ところで、C言語の場合「関数型」という型はなく、他の戻り値基本型への修飾だけで済んでいますが、この場合この名前は何になるんだろ?
    2 DW_AT_type (「関数型」の関数が戻り値を伴う「関数(function)」である場合)
    その「関数型」のDIEはこのAttributeをもっていて、その関数の戻り値の型を示すです
    3 DW_AT_prototyped プロトタイプ宣言として書かれた関数のDIEには、このAttributeがあって、trueになるです


なお、(関数の)引数に「関数型」を書く必要が有る場合は、その関数の子DIEに、引数の1つとして関数型を定義する形となるみたいで、この時の登場順はソース上の順番と同じ、とのことです。
また、この「関数型」のDIEの「子DIE」は、以下いずれかの解釈がされるものとなるです。

  • 型が明確に特定できる引数は、「DW_TAG_formal_parameter」なTAGのDIEで表示され、それぞれがもつDW_AT_typeに引数の型への参照が入ります
  • 型が特定できない引数(printfのvargなど)の場合は、「DW_TAG_unspecified_parameters」で表記されます。

※つまり、TAG詳細(その02)とあんま変わらない、ってことですね。


クラス/構造体のメンバ変数/関数へのポインタ

C++での、クラス(や構造体)へのメンバ(変数/関数)へのポインタは、「DW_TAG_ptr_to_member_type」なTAGで表示されます。

※これは、フツーのポインタの様にも思えますが、C++ではユニークな型になっています。

ということで、以下、いつもの通りのAttribute一覧です。

No. Attribute名 せつめい
1 DW_AT_name (メンバへのポインタが名前を持っている時)
このAttributeにソース上の型名をもっています(NULLおわり文字列)
2 DW_AT_type このAttributeを持っているDIEが指し示すクラスor構造体のメンバの型です
3 DW_AT_containing_type このAttributeをもっているDIEが指し示す、クラスor構造体のメンバが所属するクラスのDIEへの参照
4 DW_AT_use_location このAttributeをもっているDIEが指し示す、クラスメンバのメモリ上の格納アドレスを計算するための「Location description」が格納されています
これはもうちっと説明があるので、以下参照です。

なお、(No.4)のDW_AT_use_locationについては、「特定のメンバへのポインタ型のオブジェクト」と「クラスor構造体の実体」の関係の結合に使われるべきもの、らしいです。(そうかいてあるけど、何を言いたいのかが理解できていまへん。。。)
また、このAttributeに格納されているLocation descriptionを評価する前に、以下2つの値をDWARF expression スタックにつっこんでおく必要があります。

  • 最初の値: 「メンバへのポインタ型自身」の値
  • 2つ目の値: 構造体/unionの実体のベースアドレス(対象とするメンバを含んでいること、およびこのベースアドレスはDWARF expressionの計算がされた後のものであること、の条件あり)


最後に、原文記載の例です。

  • 以下のソース記述があったもんとするです。(原文から拝借)
        object.*mbr_prt;    // あるクラスメンバへのポインタ、です。 また、objectはクラスの実体だと思ってください。
    
  • この時、デバッガは以下のようにします。
    • 1) mbr_ptrの値(アドレス)をDWARF expressionのスタックにつっこむ
    • 2) クラスobjectのベースアドレス(つまり、&object)をDWARF expressionのスタックにつっこむ
    • 3) DW_AT_use_locationの中身(Location expression)を評価し、mbr_ptr、つまりクラスメンバへのポインタを得る。


★これも、C++を詳しくわかっていないので、なんとも言えないっす。英語の誤解はないと思ってるけど、C++でのイメージが湧かないので、あやしい!


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