ということで、今度はタイトルの通り、構造体(srtuct)、union、classです。
こいつらは、いろいろとあるので、ちと長くなりそーです。
※以上、原文前書きの「そのまんま」な訳ですが、ま、変な点はないですね。(ただーし、Pascalはワカラナイので、何とも言えない。。。)
まず、こいつら3つ自体は、以下表のTAGで表現されます。
No. | TAG名 | 対象 |
1 | DW_TAG_structure_type | 構造体 |
2 | DW_TAG_union_type | union(共用体) |
3 | DW_TAG_class_type | クラス |
そして、これらのメンバは、上記表のTAGを持つDIEの「子DIE」として表現され、この子DIEの登場順番は、ソース上の並びと同じ順です。
んで、次に上の3つのTAGが持ち得るAttributeですね。
No. | Attribute名 | せつめいでっせ |
1 | DW_AT_name | (ソース上で構造体、union、クラスに名前が与えられている場合) 構造体、union、クラスの名前(NULL終り文字列) |
2 | DW_AT_byte_size | 構造体、union、クラスのバイト単位のサイズ。 なお、もしこれらのサイズがコンパイル時に固定的に決めることができる場合、バイト数を「整数」で持ってます。 逆に、コンパイル時に決めれない時には、DWARF expressionや他のDIEへの参照など、動的にサイズを決めるためのものを持ってます |
3 | DW_AT_declaration | 以下参照でーす |
4 | DW_AT_specification | これは、以下を参照です。 |
5 | DW_AT_start_scope | この構造体、union、クラスが有効になるのが、DW_TAG_base_typeのスコープとなるTAG(一般に、親TAG)のDW_AT_low_pcからでなく、途中から始まる場合、有効となる最初のコードアドレスです。 これは「TAG詳細(その06) 変数/関数の引数/定数編」を参照です。 |
これですが、ひとことでいうと「2つの構造体やクラスに跨って分割したメンバ定義をやらかしているケース」の場合の対応です。と、いってもなんやねん、ということになっちゃうので、まず以下サンプルソースです。
// test.cpp #include<stdio.h> struct B { struct A; }; struct B::A { int temp; }; int main(int argc, char *argv[]) { struct B::A ba; ba.temp = 5; printf("%d\n", ba.temp ); return 0x00; }ちょーえーかげんな例ですが、見ての通り、
というケースです。
これ、ワタクシは知らなかった。。。のですが、「C++のソース(.cpp)なら、これコンパイル通ります!!」
(ちなみに、g++はOKですが、gccに食わせたり、test.cなファイル名にすると即死です。また、このソースに”struct A”な構造体A単体の宣言を加えてもNGです。念のため)
よーするに、C++言語では、上記の例の様に「B::A」という名前での宣言が、可能ってことです。
ただ、このケース、ふつーの書き方と比較した場合、ひとつだけ問題がありまして「構造体Aの宣言がなされていません!」
で、今回対象とする「DW_AT_declaration」「DW_AT_specification」は、こんなケースの対策用Attributeってことになるのです。ということで、これらの使われ方です。(上記サンプルの例にそって書きます)
ということで、まぁ複雑ですね。
が、さらに面倒な例があってですね。。。
なお、最後に、上のソースの例で、仮に「構造体B::A」な宣言ではなく、「構造体B」と「構造体A」がそれぞれ宣言されており、「構造体Bのメンバは構造体A」「構造体Aのメンバはint型変数」の一般的なケースであれば、このDW_AT_specification/DW_AT_declarationは登場せず、単に構造体Bの子DIE(メンバ)が、構造体Aの実体のDIEになり、この実体DIEのDW_AT_typeが「構造体A」の宣言になる、というふつーのDWARFになります。
んで、ここまで構造体、union、クラス結構めんどーでしたが、まだまだありそうです。。。
次に、構造体/union/クラスの「データメンバ」です。 なお、このセクションの記述は「メンバ関数」は同じくクラスのメンバだけど、一旦除外です。
構造体/union/クラスの「データメンバ」は、構造体/union/クラスのDIEの子DIEとして表現され、「DW_TAG_member」なタグを持っていることになってます
ということで、毎度おなじみこのTAGが持っているAttributeな一覧です。
No. | Attribute名 | いみ |
1 | DW_AT_name | ソース上でのメンバ名。(NULLエンド文字列) なお、C++での名前なしunionの場合、このAttributeは存在しないか、あっても0バイトの文字列になるです |
2 | DW_AT_type | データメンバの「型」 |
3 | DW_AT_accessibility | データメンバのアクセス記述子。 なお、このAttributeが存在しなかった場合、以下である、ということになっています 「クラス」の場合 → ”private”が指定されたものとみなす 「構造体/union/インタフェース」の場合 → ”public”が指定されたものとみなす |
4 | DW_AT_mutable | データメンバがミュータブル(内容の変更が可能かどうか)のフラグ。trueなら変更可。 よーは、スレッドセーフかどうかってことでしょうか? |
5 | DW_AT_data_member_location | (データメンバの宣言がされている)構造体、クラスの先頭アドレスを起点とした、データメンバの格納アドレス。 ちょっとめんどいので、以下参照 |
6-1 | DW_AT_byte_size | (データメンバがビットフィールドの場合) ビットフィールドのメンバ、および前後のパディングなどを含む、バイト単位のサイズ なお、DW_AT_typeの値などからサイズが自明な場合は省略されてしまうこともあります。。。 |
6-2 | DW_AT_bit_offset | (データメンバがビットフィールドの場合) もっとも左の(一番大きなビット)の左からビットフィールドが開始するビットまでのビット数 ※以下例参照 |
6-3 | DW_AT_bit_size | (データメンバがビットフィールドの場合) 対象のデータメンバが使用するビット数。 つまり、上のNo.6-2で示されたビットからこの値を足したビットまでの範囲をそのデータメンバは使うってこと。 ※以下例参照 |
このAttributeの役割は、「(データメンバの宣言がされている)構造体、クラスの先頭アドレスを起点とした、データメンバの格納アドレス。」ですが、表現方法にちょっと以下の癖ありです。
なお、unionは全てのデータメンバが同じ位置から始まりますので、このAttributeはないはずです。 また、仮に構造体Aの中に構造体Bを宣言していて(※但し、AもBもちゃんと個別に宣言されている)、構造体Bの中にあるデータメンバの場合、「構造体の先頭アドレス」は当然構造体Bの先頭アドレスになります。
ビットフィールドによるデータメンバの場合、上の表の通り「DW_AT_byte_size」「DW_AT_bit_offset」「DW_AT_bit_size」がセットで加わります。
それぞれの意味は上表の通りですが、ちと注意があるのと、原文記載の例を書いておきます
んでは、一発例です。
まず、対象のソース(ビットフィールドのC言語定義) ※原文からの拝借です
struct S { int j: 5; int k: 6; int m: 5; int n: 8;この構造体Sが、仮に32bitマシンに存在した場合
データオブジェクト名 | ビット範囲 | 左からのオフセット DW_AT_bit_offset | ビット幅 DW_AT_bit_size | 備考 |
(padding) | (31-24) | (0) | (8) | パディングなので、実際にこれは表現されないです |
n | 23-16 | 8 | 8 | |
m | 15-11 | 16 | 5 | |
k | 10-5 | 21 | 6 | |
j | 4-0 | 27 | 5 |
データオブジェクト名 | ビット範囲 | 左からのオフセット DW_AT_bit_offset | ビット幅 DW_AT_bit_size | 備考 |
j | 31-25 | 0 | 5 | |
k | 26-21 | 5 | 6 | |
m | 20-16 | 11 | 5 | |
n | 15-8 | 16 | 8 | |
(padding) | (7-0) | (24) | (8) | パディングなので、実際にこれは表現されないです |
記述子名 | value |
DW_DSC_label | 0x00 |
DW_DSC_range | 0x01 |
★この「可変部分」英訳はちょー直訳!です。ここは、英語が難解、と言う以上に、「そもそも構造体の可変部分」ってなに?ということが分かっていません。
[PageInfo]
LastUpdate: 2013-09-23 17:59:02, ModifiedBy: koinec
[License]
FreeBSD Documentation License
[Permissions]
view:all, edit:members, delete/config:members