おしながき

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詳細(その02) 関数編 ※subprogram、inlined_subroutine、entry_point

ということで、C言語で言うところの「関数」に関連するDW_TAG_xxxxな説明です。

該当のタグ

以下3種類ありますです。

No. 該当TAG名 ごせつめい
1 DW_TAG_subprogram グローバル、もしくはファイル内(でのstaticな)サブルーチン、もしくは関数
※まさしく、C言語の関数です。
2 DW_TAG_inlined_subroutine インラインサブルーチンやインライン関数のインスタンス
3 DW_TAG_entry_point (Fortran固有) 交替可能なエントリポイント

いずれも、子分として持ち得るAttributeがおんなじなんで、まとめて書くです。

(Attribute情報1) 関数やエントリポイントの一般的なAttribute

サブルーチン、関数、エントリポイントなどは、以下さまざまなAttributeを持つ可能性があります。
ということで、まず、一般的に持ち得るAttributeを御紹介です。

No. Attribute名 意味
1 DW_AT_name 関数/サブルーチン/エントリポイント名。NULL文字で終ります
2 DW_AT_external 該当するCompile Unit、すなわち関数などの実体があるオブジェクトファイル外部で定義されている関数などの場合はTrueになるフラグです。
よーするに、"extern"宣言がついているか否かですね。
3 DW_AT_calling_convention 一言でいうとその関数の「呼出規約」の種類です。これ、以下の三種類の値のいずれかになります。
1) DW_CC_normal (0x01) → ターゲットのABIの標準的な関数呼出規約の通りに呼び出すことが可能
2) DW_CC_nocall (0x03) → ターゲットABIの標準的な呼出規約に「準拠していない」関数を示す
3) DW_CC_program (0x02) → そのプログラム自体を呼び出す(起動)場合の呼出規約。つまり、main関数の場合
この値、何のために持っているかというと、デバッガって、プログラム中の関数をデバッガ上から直接呼び出せちゃうわけですが、この際、デバッガはふつー一般的な呼出規約で、呼び出します。
ただし、コンパイラ君の都合や手動アセンブルでABI無視して高速な呼び出しチューンをやってたりする関数に、一般呼出規約でcallすると。。。やばぁいわけです。
ので、これをデバッガに伝えるため、設けられています。
ちなみに、main関数を区別しているのも、main関数の呼出規約は、ふつーの関数と、当然違うためです。
あと、このAttribute指定なし=DW_CC_normal指定と見なされます。
4 DW_AT_elemental ソースコード上で"elemental"なキーワードがサブルーチンに指定されている場合、ture
※事実上、Fortran専用?
5 DW_AT_pure ソースコード上で"pure"なキーワードがサブルーチンに指定されている場合、ture
※事実上、Fortran専用?
6 DW_AT_recursive ソースコード上で"recursive"なキーワードがサブルーチンに指定されている場合、ture
※事実上、Fortran専用? なお、このAttributeは、原文上で、CやC++などのよーに再帰関数にもできることが前提な言語では「持たない」と明言されています


(Attribute情報2) 関数やエントリポイントの戻り値型

No. Attribute名 意味
7 DW_AT_type 戻り値型を定義するです
なお、CやC++のvoid型の関数の場合、この属性は持ちません。(voidと言う形での定義はされないってことです。ま、値返してくれないのだから、いらんけどね)
8 DW_AT_prototyped 対象の関数の宣言が「プロトタイプ宣言」なら、tureになります。


(Attribute情報3) 関数やエントリポイントのコードアドレス情報

No. Attribute名 意味
9 1) DW_AT_low_pc & DW_AT_high_pc
2) DW_AT_ranges
マシン命令の連続する(1)、連続しない(2)、範囲を示す。
つまり、このAttributeで示されるコードアドレスの範囲内に、該当の関数の命令が埋まってるってことです
10 DW_AT_entry_pc 関数/サブルーチンの最初の実行可能な命令のアドレス (entry_pcが持つアドレスは、再配置後のアドレスでない、つまり、リンク前のアドレスの可能性あり)
※注意: 再配置後、つまりデバッガが通常相手にする関数の最初の実行可能な命令アドレスは、DW_AT_low_pcが(DWARFな伝統的に)持つことになってる。と原文に明記ありです。
(さらに、コンパイラ屋には、特段理由なく、この伝統を変えるな、とも)
11 DW_AT_segment & DW_AT_address_class 関数/サブルーチンのコードアドレスの指定にセグメントなど、特殊な指定方法が必要な場合持ちます。
「セグメント」って言えば、無論好例は、INTEL x86 (16bit/32bit)です。
詳細は、原文pp29-30 2.12 Segmented Address にあるけど、当面32bitはおあずけのため、省略です


(Attribute情報4) 関数やエントリポイント内での宣言

関数内での宣言は、なんかのAttributeで表現されちゃうわけではなく、以下の様に子DIEとの形で表現されますです。以下、そのルールデス。

  • 関数/サブルーチン/エントリポイント内の宣言(変数など)は、関数/サブルーチン/エントリポイントのDIEの子DIEとして表現されますです。
  • んで、これらパラメタなどの宣言は、ソースコード上とおんなじ順番で並んでるよ、とのことでごわすです。
  • 可変パラメタ(vargなど)の様に、明確に宣言されないパラメタ君は、DW_TAG_upspecified_parametersなTAGとして表現されちゃいます。
  • Fortranでの共通ブロックを含むサブルーチンのDIEは、子DIEとしてDW_TAG_common_inclusionなTAGを持つことになってます。
    • んで、このDIEは、DW_AT_common_referenceなAttributeを持っていて、このAttributeはインクルードされた共通ブロックへのDIEの参照を持っている、てな仕組みになってるらしいです。(※Fortranはとりあえずコード見て蕁麻疹が出ない程度しか分からないです=共通ブロックって理解できていず、これはスーパー直訳でございますです)


(Attribute情報5) 低レベルな情報

「低レベルな情報」って言葉(=原文直訳)は、おいおい。。。なんですが、これ実体は関数の「フレームベースや戻りアドレス」のお話しです。

No. Attribute名 意味
12 DW_AT_return_addr 関数やサブルーチン戻りアドレス(の格納場所)を求めるためのLocation Description(DWARF Expression)を指します。
13 DW_AT_frame_base 関数やサブルーチンの”フレームベースアドレス”を求めるためのLocation Descriptionが入ってます
なお、このLocation Description、入ってる内容によって以下2パターンありです。
* レジスタ操作命令である場合→そのレジスタにフレームベースアドレスが入ってます
* (レジスタ操作以外の)DWARF Expressoinの場合→DWARF expressionの評価結果がフレームベースアドレスの値でごわす
※「さらに、 location listの場合? →この解釈はlocation listエントリのリストを含むそれぞれのLocation expressionにあてはまる」 的な英文があるのですが、直訳でしかなく、にゃに言っているのか不明。。。(とほほ)
14 DW_AT_static_link サブルーチンやエントリポイントがネストしている場合、対象のサブルーチンが抱える、直下のサブルーチンのインスタンスのフレームベースアドレスを計算するためのLocation Descriptionをもってます
んで、このAttributeをもつ場合は、DW_AT_frame_baseの持つ値には、以下2つの制約があるです
1) プロシージャが生きている間は変わらないフレームベースアドレスが計算できる値をもつ、かつ
2) 計算されたフレームベースアドレスは同じサブルーチンのたくさんあるインスタンス内でユニークなものとなる(これはつまるところ、再帰的なサブルーチンのスタックフレームのサイズは0じゃなくって、有る程度のサイズが常にスタックにつまさっていく、ってコメントありです)
※ ところで、この「サブルーチンやエントリポインのネスト」って、CやC++じゃない、なんかの言語でサポートしてるってのは聞いたことがあるけど、なんだっけ忘れた。。。


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