おしながき

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ファイルフォーマット

.debug_macinfoセクションの構造:解析編

というわけで、少し.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コマンドの結果

では、バイナリダンプを、と行きたいところですが、今回はちょっと嗜好をかえて、まず「答え」に相当する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は終りです。


しめくくり by .debug_macinfo

今回も、ダンプ解析はバチっと合いましたんで、無事終りっす。
ただ、ここまでやっていうのも何ですが、このmacinfoの最大級の問題点として、いちいちgccに"-g3"で発注しないと出してくんない!

→ 通常、使わなくてもデバッグできちゃう、の点に付きます。

確かに、この情報デバッガでどーやって活用するのだろ、って気にもなりますね。
まぁ、ただこーなてんだって意味ではお勉強になりましたです。


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