というわけで、少し.debug_macinfoセクションの構造は長くなり、さらに解析編も例が多くて長くなりそうなんで、分割しますた。
いけにえソースは、以下2つをつかってます。
それでは、1本目。ちなみに、今回は説明に必要なんで、行番号を入れてみました。
/* .debug_macinfo sample source -- test1.c */ 1 #include"macrotest.h" 2 3 int main(int argc, char *argv[]) { 4 int a, b, c; 5 char *str; 6 7 a = 1; 8 b = CONST_INT; 9 c = MFUNC1( a, b ); 10 11 str = CONST_STR; 12 13 return 0x00; 14 }
んで、2発目。これは、マクロをイロイロ書いた、ヘッダファイルです。
/* .debug_macinfo sample source -- macrotest.h */ 1 #pragma once 2 3 #define CONST_INT 5 4 #define CONST_STR "koinec" 5 6 #define MFUNC1(n,m) (n)+(m) 7 8 #if CONST_INT > 4 9 #define MACRO_IF_OK 10 10 #endif 11 12 #if CONST_INT > 10 13 #define MACRO_NG 100 14 #endif
というわけで、今回はこいつら2本を"-g3"オプション付きでコンパイルしてます。[[BR] 使った環境は、前とおんなじで、これです。
prompt # uname -a FreeBSD xxxx.koinec.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #0: amd64 prompt # gcc -v Using built-in specs. Target: amd64-undermydesk-freebsd Configured with: FreeBSD/amd64 system compiler Thread model: posix gcc version 4.2.1 20070831 patched [FreeBSD]
では、バイナリダンプを、と行きたいところですが、今回はちょっと嗜好をかえて、まず「答え」に相当するreadelfコマンドの結果を先に見て行きます。
ちょっと分量がありますが、.debug_macinfoセクションを"readelf -w"で解析した結果です。はてさて、macrotest.hでは5つしかマクロ定義してないんですがねぇ〜なんでこんなんあるの?
あ、ちなみにこれも行番号いれちゃいました。
1 Contents of the .debug_macinfo section: 2 3 DW_MACINFO_start_file - lineno: 0 filenum: 1 4 DW_MACINFO_define - lineno : 0 macro : __STDC__ 1 5 DW_MACINFO_define - lineno : 0 macro : __STDC_HOSTED__ 1 6 DW_MACINFO_define - lineno : 0 macro : __GNUC__ 4 7 DW_MACINFO_define - lineno : 0 macro : __GNUC_MINOR__ 2 8 DW_MACINFO_define - lineno : 0 macro : __GNUC_PATCHLEVEL__ 1 9 DW_MACINFO_define - lineno : 0 macro : __SIZE_TYPE__ long unsigned int 10 DW_MACINFO_define - lineno : 0 macro : __PTRDIFF_TYPE__ long int 11 DW_MACINFO_define - lineno : 0 macro : __WCHAR_TYPE__ int 12 DW_MACINFO_define - lineno : 0 macro : __WINT_TYPE__ int 13 DW_MACINFO_define - lineno : 0 macro : __INTMAX_TYPE__ long int 14 DW_MACINFO_define - lineno : 0 macro : __UINTMAX_TYPE__ long unsigned int 15 DW_MACINFO_define - lineno : 0 macro : __GXX_ABI_VERSION 1002 16 DW_MACINFO_define - lineno : 0 macro : __SCHAR_MAX__ 127 17 DW_MACINFO_define - lineno : 0 macro : __SHRT_MAX__ 32767 18 DW_MACINFO_define - lineno : 0 macro : __INT_MAX__ 2147483647 19 DW_MACINFO_define - lineno : 0 macro : __LONG_MAX__ 9223372036854775807L 20 DW_MACINFO_define - lineno : 0 macro : __LONG_LONG_MAX__ 9223372036854775807LL 21 DW_MACINFO_define - lineno : 0 macro : __WCHAR_MAX__ 2147483647 22 DW_MACINFO_define - lineno : 0 macro : __CHAR_BIT__ 8 23 DW_MACINFO_define - lineno : 0 macro : __INTMAX_MAX__ 9223372036854775807L 24 DW_MACINFO_define - lineno : 0 macro : __FLT_EVAL_METHOD__ 0 25 DW_MACINFO_define - lineno : 0 macro : __DEC_EVAL_METHOD__ 2 26 DW_MACINFO_define - lineno : 0 macro : __FLT_RADIX__ 2 27 DW_MACINFO_define - lineno : 0 macro : __FLT_MANT_DIG__ 24 28 DW_MACINFO_define - lineno : 0 macro : __FLT_DIG__ 6 29 DW_MACINFO_define - lineno : 0 macro : __FLT_MIN_EXP__ (-125) 30 DW_MACINFO_define - lineno : 0 macro : __FLT_MIN_10_EXP__ (-37) 31 DW_MACINFO_define - lineno : 0 macro : __FLT_MAX_EXP__ 128 32 DW_MACINFO_define - lineno : 0 macro : __FLT_MAX_10_EXP__ 38 33 DW_MACINFO_define - lineno : 0 macro : __FLT_MAX__ 3.40282347e+38F 34 DW_MACINFO_define - lineno : 0 macro : __FLT_MIN__ 1.17549435e-38F 35 DW_MACINFO_define - lineno : 0 macro : __FLT_EPSILON__ 1.19209290e-7F 36 DW_MACINFO_define - lineno : 0 macro : __FLT_DENORM_MIN__ 1.40129846e-45F 37 DW_MACINFO_define - lineno : 0 macro : __FLT_HAS_DENORM__ 1 38 DW_MACINFO_define - lineno : 0 macro : __FLT_HAS_INFINITY__ 1 39 DW_MACINFO_define - lineno : 0 macro : __FLT_HAS_QUIET_NAN__ 1 40 DW_MACINFO_define - lineno : 0 macro : __DBL_MANT_DIG__ 53 41 DW_MACINFO_define - lineno : 0 macro : __DBL_DIG__ 15 42 DW_MACINFO_define - lineno : 0 macro : __DBL_MIN_EXP__ (-1021) 43 DW_MACINFO_define - lineno : 0 macro : __DBL_MIN_10_EXP__ (-307) 44 DW_MACINFO_define - lineno : 0 macro : __DBL_MAX_EXP__ 1024 45 DW_MACINFO_define - lineno : 0 macro : __DBL_MAX_10_EXP__ 308 46 DW_MACINFO_define - lineno : 0 macro : __DBL_MAX__ 1.7976931348623157e+308 47 DW_MACINFO_define - lineno : 0 macro : __DBL_MIN__ 2.2250738585072014e-308 48 DW_MACINFO_define - lineno : 0 macro : __DBL_EPSILON__ 2.2204460492503131e-16 49 DW_MACINFO_define - lineno : 0 macro : __DBL_DENORM_MIN__ 4.9406564584124654e-324 50 DW_MACINFO_define - lineno : 0 macro : __DBL_HAS_DENORM__ 1 51 DW_MACINFO_define - lineno : 0 macro : __DBL_HAS_INFINITY__ 1 52 DW_MACINFO_define - lineno : 0 macro : __DBL_HAS_QUIET_NAN__ 1 53 DW_MACINFO_define - lineno : 0 macro : __LDBL_MANT_DIG__ 64 54 DW_MACINFO_define - lineno : 0 macro : __LDBL_DIG__ 18 55 DW_MACINFO_define - lineno : 0 macro : __LDBL_MIN_EXP__ (-16381) 56 DW_MACINFO_define - lineno : 0 macro : __LDBL_MIN_10_EXP__ (-4931) 57 DW_MACINFO_define - lineno : 0 macro : __LDBL_MAX_EXP__ 16384 58 DW_MACINFO_define - lineno : 0 macro : __LDBL_MAX_10_EXP__ 4932 59 DW_MACINFO_define - lineno : 0 macro : __DECIMAL_DIG__ 21 60 DW_MACINFO_define - lineno : 0 macro : __LDBL_MAX__ 1.18973149535723176502e+4932L 61 DW_MACINFO_define - lineno : 0 macro : __LDBL_MIN__ 3.36210314311209350626e-4932L 62 DW_MACINFO_define - lineno : 0 macro : __LDBL_EPSILON__ 1.08420217248550443401e-19L 63 DW_MACINFO_define - lineno : 0 macro : __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L 64 DW_MACINFO_define - lineno : 0 macro : __LDBL_HAS_DENORM__ 1 65 DW_MACINFO_define - lineno : 0 macro : __LDBL_HAS_INFINITY__ 1 66 DW_MACINFO_define - lineno : 0 macro : __LDBL_HAS_QUIET_NAN__ 1 67 DW_MACINFO_define - lineno : 0 macro : __DEC32_MANT_DIG__ 7 68 DW_MACINFO_define - lineno : 0 macro : __DEC32_MIN_EXP__ (-95) 69 DW_MACINFO_define - lineno : 0 macro : __DEC32_MAX_EXP__ 96 70 DW_MACINFO_define - lineno : 0 macro : __DEC32_MIN__ 1E-95DF 71 DW_MACINFO_define - lineno : 0 macro : __DEC32_MAX__ 9.999999E96DF 72 DW_MACINFO_define - lineno : 0 macro : __DEC32_EPSILON__ 1E-6DF 73 DW_MACINFO_define - lineno : 0 macro : __DEC32_DEN__ 0.000001E-95DF 74 DW_MACINFO_define - lineno : 0 macro : __DEC64_MANT_DIG__ 16 75 DW_MACINFO_define - lineno : 0 macro : __DEC64_MIN_EXP__ (-383) 76 DW_MACINFO_define - lineno : 0 macro : __DEC64_MAX_EXP__ 384 77 DW_MACINFO_define - lineno : 0 macro : __DEC64_MIN__ 1E-383DD 78 DW_MACINFO_define - lineno : 0 macro : __DEC64_MAX__ 9.999999999999999E384DD 79 DW_MACINFO_define - lineno : 0 macro : __DEC64_EPSILON__ 1E-15DD 80 DW_MACINFO_define - lineno : 0 macro : __DEC64_DEN__ 0.000000000000001E-383DD 81 DW_MACINFO_define - lineno : 0 macro : __DEC128_MANT_DIG__ 34 82 DW_MACINFO_define - lineno : 0 macro : __DEC128_MIN_EXP__ (-6143) 83 DW_MACINFO_define - lineno : 0 macro : __DEC128_MAX_EXP__ 6144 84 DW_MACINFO_define - lineno : 0 macro : __DEC128_MIN__ 1E-6143DL 85 DW_MACINFO_define - lineno : 0 macro : __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL 86 DW_MACINFO_define - lineno : 0 macro : __DEC128_EPSILON__ 1E-33DL 87 DW_MACINFO_define - lineno : 0 macro : __DEC128_DEN__ 0.000000000000000000000000000000001E-6143DL 88 DW_MACINFO_define - lineno : 0 macro : __REGISTER_PREFIX__ 89 DW_MACINFO_define - lineno : 0 macro : __USER_LABEL_PREFIX__ 90 DW_MACINFO_define - lineno : 0 macro : __VERSION__ "4.2.1 20070831 patched [FreeBSD]" 91 DW_MACINFO_define - lineno : 0 macro : __GNUC_GNU_INLINE__ 1 92 DW_MACINFO_define - lineno : 0 macro : _LP64 1 93 DW_MACINFO_define - lineno : 0 macro : __LP64__ 1 94 DW_MACINFO_define - lineno : 0 macro : __NO_INLINE__ 1 95 DW_MACINFO_define - lineno : 0 macro : __FINITE_MATH_ONLY__ 0 96 DW_MACINFO_define - lineno : 0 macro : __amd64 1 97 DW_MACINFO_define - lineno : 0 macro : __amd64__ 1 98 DW_MACINFO_define - lineno : 0 macro : __x86_64 1 99 DW_MACINFO_define - lineno : 0 macro : __x86_64__ 1 100 DW_MACINFO_define - lineno : 0 macro : __MMX__ 1 101 DW_MACINFO_define - lineno : 0 macro : __SSE__ 1 102 DW_MACINFO_define - lineno : 0 macro : __SSE2__ 1 103 DW_MACINFO_define - lineno : 0 macro : __SSE_MATH__ 1 104 DW_MACINFO_define - lineno : 0 macro : __SSE2_MATH__ 1 105 DW_MACINFO_define - lineno : 0 macro : __k8 1 106 DW_MACINFO_define - lineno : 0 macro : __k8__ 1 107 DW_MACINFO_define - lineno : 0 macro : __FreeBSD__ 9 108 DW_MACINFO_define - lineno : 0 macro : __unix 1 109 DW_MACINFO_define - lineno : 0 macro : __unix__ 1 110 DW_MACINFO_define - lineno : 0 macro : unix 1 111 DW_MACINFO_define - lineno : 0 macro : __unix__ 1 112 DW_MACINFO_define - lineno : 0 macro : __KPRINTF_ATTRIBUTE__ 1 113 DW_MACINFO_define - lineno : 0 macro : __FreeBSD_cc_version 900001 114 DW_MACINFO_define - lineno : 0 macro : __LP64__ 1 115 DW_MACINFO_define - lineno : 0 macro : __ELF__ 1 116 DW_MACINFO_define - lineno : 0 macro : _LONGLONG 1 117 DW_MACINFO_start_file - lineno: 1 filenum: 2 118 DW_MACINFO_define - lineno : 3 macro : CONST_INT 5 119 DW_MACINFO_define - lineno : 4 macro : CONST_STR "koinec" 120 DW_MACINFO_define - lineno : 6 macro : MFUNC1(n,m) (n)+(m) 121 DW_MACINFO_define - lineno : 9 macro : MACRO_IF_OK 10 122 DW_MACINFO_end_file 123 DW_MACINFO_end_file
というわけで、ここまでを前提として、以下.debug_macinfoセクションのバイナリダンプを解析していきます。
なお、以下に入れていますが、途中を省いています。長すぎるからです。よって、上にreadelfを入れましたんで、全部みたいひとはこっち見てくださいです。要点は全部押えたはず。
あ、ちなみに行頭が" #"の行はわたくしが書いたコメント、" *"は上のreadelfの対応する行です。
# Hex. Dump by .debug_macinfo # まず、.debug_macinfoの最初のバイトから見て行きます。 00000000 03 00 01 * DW_MACINFO_start_file - lineno: 0 filenum: 1 # いきなりですが、ヘッダも何もなく、この行です。 # まず、0x03 なんで、DW_MACINFO_start_file命令と分かります。 # で、次が0x00です。これはuLEB128表現で0です。 # なので、#includeは0行目にあることが分かります。 # ところで、ん?0行目、なんてないですよね。 # これから、この行はコンパイラが勝手につっこんだことが分かります。 # そして、次のバイト0x01です。これもuLEB128でも、1です。 # この2バイト目は、先の表から、.debug_line上のファイルテーブルのIDでした。 # なので、.debug_line上のファイルテーブルID 1のファイルにインクルードすることが # 分かります。では、ファイルテーブルIDの1は何?ですね。 # 以下に、参考としてファイルテーブルIDを張り付けておきます。 # # The File Name Table: # Entry Dir Time Size Name # 1 0 0 0 test1.c # 2 0 0 0 macrotest.h # # これから、ID=1は、test1.cですね。 # ん?test1.cはインクルードできない(してない)ですよね。 # これは、コンパイラ勝手挿入マクロの場合のみ、挿入先のソースファイルの番号を # 指定してしまうようです。 # これは、前の分析のページで、規約上"-"のファイル名を指す、と書きましたが、 # gccの実装は異なっているようです。。。(どっちが、正しいのだろう。。。) # で、次の命令にいきます。 00000003 01 00 5f 5f 53 54 44 43 5f 5f 20 31 00 : 0x01 0x00 "__STDC__ 1" * DW_MACINFO_define - lineno : 0 macro : __STDC__ 1 # まず、1Byte目 = 0x01 から、DW_MACINFO_defineとわかります。 # 次に、2Byte目 = 0x00。これは、定義のソース行番号ですが、0行目、です。 # なので、コンパイラが勝手につっこんだマクロですね。 # 最後に、その次からのバイトです。これは、NULL終りの文字列ですね。 # この文字列は、"__STDC__ 1"です。これが、マクロの定義文ですね。 # 次も、同じようなコンパイラ勝手つっこみマクロです。 00000010 01 00 5f 5f 53 54 44 43 5f 48 4f 53 54 45 44 5f 5f 20 31 00 __STDC_HOSTED__ 1 * DW_MACINFO_define - lineno : 0 macro : __STDC_HOSTED__ 1 # で、ここから115行、コンパイラ勝手挿入マクロです。ので、省略。 # そして、117行目です。 00000b37 03 01 02 * DW_MACINFO_start_file - lineno: 1 filenum: 2 # まず、0x03 = DW_MACINFO_start_fileですね。 # 次に、0x01は、uLEB128表現でも、1です。なので、1行目にあります。 # では、上のソース見てみましょう。1行目に、"#include"macrotest.h"があります。 # 最後に、0x02 です。uLEB128でも2です。これは、.debug_line上のファイルテーブルIDです。 # ファイルテーブルのNo.2はというと、"macrotest.h"ですね。 # これから、きちんとmacrotest.hをインクルードするよって、分かりますね。 00000b3a 01 03 43 4f 4e 53 54 5f 49 4e 54 20 35 00 : 0x01 0x03 "CONST_INT 5" * DW_MACINFO_define - lineno : 3 macro : CONST_INT 5 # その次です。まず0x01なので、DW_MACINFO_defineです。 # 次のByteは、0x03です。これはuLEB128で、3行目ですね。 # ソースを見ると、"#define CONST_INT 5"は、macrotest.hの3行目にありますね。 # そして、NULL終り文字列は"CONST_INT 5"です。ソースから見ても、OKです。 00000b48 01 04 43 4f 4e 53 54 5f 53 54 52 20 22 6b 6f 69 6e 65 63 22 00 : 0x01 0x04 "CONST_STR "koinec"" * DW_MACINFO_define - lineno : 4 macro : CONST_STR "koinec" # これも、上と同じです。大丈夫ですな。 00000b5d 01 06 4d 46 55 4e 43 31 28 6e 2c 6d 29 20 28 6e 29 2b 28 6d 29 00 : 0x01 0x06 "MFUNC1(n,m) (n)+(m)" * DW_MACINFO_define - lineno : 6 macro : MFUNC1(n,m) (n)+(m) # 関数マクロの例ですが、これもそのまま出てますね。 00000b73 01 09 4d 41 43 52 4f 5f 49 46 5f 4f 4b 20 31 30 00 : 0x01 0x09 "MACRO_IF_OK 10" * DW_MACINFO_define - lineno : 9 macro : MACRO_IF_OK 10 # このマクロ、ソースを見てみてくださいです。 # この行の前に"#if CONST_INT > 4"があり、その下に"#endif"がありますが、 # これが一切出力されず、最終的に評価された後のMACRO_IF_OKの定義だけが # 出力されていることが分かります。 # はい、これから分かったこと # = #if/#endif(恐らく#ifdef/#ifndef/#else)は、出力されません 00000b84 04 * DW_MACINFO_end_file # 0x04 なので、DW_MACINFO_end_fileです。 # 引数はないので、これでOKです。 # ところで、これは「コンパイラが勝手に作ったマクロ」「macrotest.h」どちらの # 終了なのでしょうか。。。。これ、分かりません。 00000b85 04 * DW_MACINFO_end_file # (上からの続き) # ただ、この定義が.debug_macinfoの最後ですが、これも0x04=DW_MACINFO_end_fileです。 # よーするに、ソースの最後にDW_MACINFO_end_fileがインクルードしたファイル数分、 # まとまって出力されちゃう、が正解みたいです。 # よって、どのファイルのend_fileかって、特定はしなくてもいいみたいです。 # ということで、これで.debug_macinfoは終りです。
今回も、ダンプ解析はバチっと合いましたんで、無事終りっす。
ただ、ここまでやっていうのも何ですが、このmacinfoの最大級の問題点として、いちいちgccに"-g3"で発注しないと出してくんない!
確かに、この情報デバッガでどーやって活用するのだろ、って気にもなりますね。
まぁ、ただこーなてんだって意味ではお勉強になりましたです。
[PageInfo]
LastUpdate: 2013-05-28 22:15:36, ModifiedBy: koinec
[License]
FreeBSD Documentation License
[Permissions]
view:all, edit:members, delete/config:members