DWARFは、ソースプログラムについてコンパイラが知っていることを表すものです。したがって、この質問に対する一般的な答えは、ソースで「ローカル」のサイズを見つけることができれば、そうです。そうでなければいいえ。
この場合、プログラムから...
を削除してコンパイルすると、readelf
を使用して直接DWARFを読み取ることができます。
はここmain
でtestarray
は次のようになります。
<2><5c>: Abbrev Number: 3 (DW_TAG_variable)
<5d> DW_AT_name : (indirect string, offset: 0x5): testarray
<61> DW_AT_decl_file : 1
<62> DW_AT_decl_line : 7
<63> DW_AT_type : <0x7f>
<67> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
...
<1><7f>: Abbrev Number: 7 (DW_TAG_array_type)
<80> DW_AT_type : <0x78>
<84> DW_AT_sibling : <0x8f>
<2><88>: Abbrev Number: 8 (DW_TAG_subrange_type)
<89> DW_AT_type : <0x8f>
<8d> DW_AT_upper_bound : 5
<2><8e>: Abbrev Number: 0
<1><8f>: Abbrev Number: 6 (DW_TAG_base_type)
<90> DW_AT_byte_size : 8
<91> DW_AT_encoding : 7 (unsigned)
<92> DW_AT_name : (indirect string, offset: 0x60): sizetype
それは6つの文字の配列である、すなわち。したがって、この場合、長さを正確に知ることができます。 - 他の言葉で、長さが静的に知られていない
<2><4e>: Abbrev Number: 3 (DW_TAG_variable)
<4f> DW_AT_name : (indirect string, offset: 0xf): teststr
<53> DW_AT_decl_file : 1
<54> DW_AT_decl_line : 6
<55> DW_AT_type : <0x72>
<59> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24)
...
<1><72>: Abbrev Number: 5 (DW_TAG_pointer_type)
<73> DW_AT_byte_size : 8
<74> DW_AT_type : <0x78>
<1><78>: Abbrev Number: 6 (DW_TAG_base_type)
<79> DW_AT_byte_size : 1
<7a> DW_AT_encoding : 6 (signed char)
<7b> DW_AT_name : (indirect string, offset: 0x7d): char
これは、それだけでポインタに-文字でこう述べています。しかしteststr
とfunc
の変数
は、より多くのように見えます。 gdbのようなデバッガは、実行時に下位からメモリを読み出すことで、プログラムのように長さを見つけることができます。
ありがとうございます!あなたは、上記のDWARF情報からtestarrayが6文字の配列であることをどのように伝えることができるのか説明できますか?私が正しく推測すれば、 "DW_AT_upper_bound"からそれを知ることができます。次に私の質問は、mainに複数の配列がある場合、どのように対応する配列とそれぞれ異なる "DW_AT_upper_bound"を一致させることができるのでしょうか? –
それはすべてタイプに基づいています。最初に、変数 'testarray' - DIE 0x5cのエントリを見つけることができます。次に、配列の型(DIE 0x7f)を調べます。型は配列型なので、境界を見てください。下限は0です(明示的ではありませんが、CUの言語に基づいて知ることができます)。上限は5です - 長さは6です。関数内の他の配列は、独自の境界を持つ独自の型を持ちます。 –