ということで、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を持つ可能性があります。
ということで、まず、一般的に持ち得る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++などのよーに再帰関数にもできることが前提な言語では「持たない」と明言されています |
No. | Attribute名 | 意味 |
7 | DW_AT_type | 戻り値型を定義するです なお、CやC++のvoid型の関数の場合、この属性は持ちません。(voidと言う形での定義はされないってことです。ま、値返してくれないのだから、いらんけどね) |
8 | DW_AT_prototyped | 対象の関数の宣言が「プロトタイプ宣言」なら、tureになります。 |
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で表現されちゃうわけではなく、以下の様に子DIEとの形で表現されますです。以下、そのルールデス。
「低レベルな情報」って言葉(=原文直訳)は、おいおい。。。なんですが、これ実体は関数の「フレームベースや戻りアドレス」のお話しです。
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++じゃない、なんかの言語でサポートしてるってのは聞いたことがあるけど、なんだっけ忘れた。。。 |
[PageInfo]
LastUpdate: 2013-09-04 21:44:32, ModifiedBy: koinec
[License]
FreeBSD Documentation License
[Permissions]
view:all, edit:members, delete/config:members