[インデックス 15310] ファイルの概要
このコミットは、Go言語のデバッグ情報フォーマットであるDWARFの処理に関連するものです。具体的には、debug/dwarf
パッケージにformFlagPresent
という新しい属性エンコーディングを追加し、それに対応する処理を実装しています。これにより、DWARFv4で導入された新しいフラグ形式を正しく解釈できるようになります。
コミット
commit 7fdaec6c2fbed0d4a5a52644e9198b5bbb4f8c6f
Author: Robin Eklind <r.eklind.87@gmail.com>
Date: Wed Feb 20 00:58:31 2013 +0800
debug/dwarf: add flag_present attribute encoding.
ref: http://www.dwarfstd.org/doc/DWARF4.pdf
Update #4829
R=minux.ma, iant
CC=dave, golang-dev
https://golang.org/cl/7354043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/7fdaec6c2fbed0d4a5a52644e9198b5bbb4f8c6f
元コミット内容
debug/dwarf: add flag_present attribute encoding.
ref: http://www.dwarfstd.org/doc/DWARF4.pdf
Update #4829
変更の背景
この変更は、DWARFデバッグ情報フォーマットのバージョン4(DWARFv4)で導入された新しい属性エンコーディングであるDW_FORM_flag_present
に対応するために行われました。DWARFは、コンパイラが生成する実行可能ファイルにデバッグ情報を埋め込むための標準フォーマットであり、デバッガがプログラムの実行状態を解析するために使用します。
以前のDWARFバージョンでは、ブール値のフラグ属性は通常DW_FORM_flag
(1バイトの真偽値)としてエンコードされていました。しかし、DWARFv4では、属性が存在すること自体が真を意味し、値がエンコードされないDW_FORM_flag_present
という形式が追加されました。これは、属性の存在がその意味を伝える場合に、余分なバイトを節約するための最適化です。
Go言語のdebug/dwarf
パッケージは、DWARFデバッグ情報を解析するためのライブラリであり、新しいDWARFv4の形式を正しく解釈できるように更新する必要がありました。このコミットは、その対応の一環として、DW_FORM_flag_present
のエンコーディングとデコードロジックを追加しています。
前提知識の解説
DWARF (Debugging With Attributed Record Formats)
DWARFは、ソースレベルデバッガがプログラムの実行を解析するために必要な情報を、コンパイルされたプログラムに埋め込むための標準的なデバッグ情報フォーマットです。主にC、C++、Goなどのコンパイル型言語で使用されます。
DWARFは、以下のような情報を提供します。
- ソースファイルと行番号のマッピング: 実行中のコードがどのソースファイルのどの行に対応するか。
- 変数情報: 変数の名前、型、メモリ上の位置。
- 関数情報: 関数の名前、引数、戻り値、ローカル変数。
- 型情報: 構造体、配列、ポインタなどの複雑なデータ型の定義。
- スタックフレーム情報: 関数呼び出しスタックの構造。
DWARF情報は、実行可能ファイルの.debug_info
、.debug_abbrev
、.debug_line
などのセクションに格納されます。
DWARFの属性とフォーム (Attributes and Forms)
DWARFでは、デバッグ情報エントリ(DIE: Debugging Information Entry)がプログラム要素(変数、関数、型など)を記述します。各DIEは、その要素に関する詳細情報を提供する一連の「属性(Attributes)」を持ちます。例えば、変数のDIEはDW_AT_name
(名前)、DW_AT_type
(型)、DW_AT_location
(場所)などの属性を持つことができます。
各属性は、その値がどのようにエンコードされているかを示す「フォーム(Form)」を持ちます。フォームは、値のデータ型とサイズを定義します。例えば、DW_FORM_string
はNULL終端文字列、DW_FORM_data4
は4バイトのデータ、DW_FORM_addr
はアドレスを表します。
DW_FORM_flag
と DW_FORM_flag_present
DW_FORM_flag
: これはDWARFの初期バージョンから存在するフォームで、ブール値(真/偽)の属性をエンコードするために使用されます。通常、1バイトのデータとして格納され、0は偽、1は真を表します。DW_FORM_flag_present
: DWARFv4で導入された新しいフォームです。このフォームは、属性が存在すること自体が「真」を意味し、属性値自体はデバッグ情報エントリにエンコードされません。つまり、このフォームを持つ属性は、その属性が存在するかどうかだけで意味を持ち、追加のデータは不要です。これにより、デバッグ情報のサイズを削減できます。
例えば、ある関数がインライン化されているかどうかを示すDW_AT_inline
属性を考えてみましょう。もしDW_AT_inline
属性がDW_FORM_flag_present
として存在すれば、その関数はインライン化されていると解釈されます。属性が存在しなければ、インライン化されていないと解釈されます。
技術的詳細
このコミットは、Go言語のdebug/dwarf
パッケージにおいて、DW_FORM_flag_present
という新しいDWARFフォームを認識し、処理できるようにするための変更です。
-
src/pkg/debug/dwarf/const.go
の変更:formFlagPresent
という新しい定数が追加されています。この定数には、DWARF仕様で定義されているDW_FORM_flag_present
の数値(0x19
)が割り当てられています。これにより、Goのコード内でこの新しいフォームを識別できるようになります。
-
src/pkg/debug/dwarf/entry.go
の変更:buf
構造体のentry
メソッド内に、formFlagPresent
を処理するための新しいcase
文が追加されています。case formFlagPresent:
ブロックでは、val = true
と設定されています。これは、DW_FORM_flag_present
属性の場合、その属性が存在すること自体が真を意味するため、明示的な値を読み込む必要がなく、常にtrue
として解釈されることを示しています。- コメントで「The attribute is implicitly indicated as present, and no value is encoded in the debugging information entry itself.」と説明されており、このフォームの特性が明確に示されています。
この変更により、GoのデバッガやツールがDWARFv4形式のデバッグ情報を含むバイナリを解析する際に、DW_FORM_flag_present
属性を正しく解釈し、対応するブール値として扱うことができるようになります。
コアとなるコードの変更箇所
src/pkg/debug/dwarf/const.go
--- a/src/pkg/debug/dwarf/const.go
+++ b/src/pkg/debug/dwarf/const.go
@@ -207,6 +207,7 @@ const (
formRef8 format = 0x14
formRefUdata format = 0x15
formIndirect format = 0x16
+ formFlagPresent format = 0x19
)
// A Tag is the classification (the type) of an Entry.
src/pkg/debug/dwarf/entry.go
--- a/src/pkg/debug/dwarf/entry.go
+++ b/src/pkg/debug/dwarf/entry.go
@@ -185,6 +185,10 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
// flag
case formFlag:
val = b.uint8() == 1
+ case formFlagPresent:
+ // The attribute is implicitly indicated as present, and no value is
+ // encoded in the debugging information entry itself.
+ val = true
// reference to other entry
case formRefAddr:
コアとなるコードの解説
src/pkg/debug/dwarf/const.go
このファイルは、DWARFの様々な定数(タグ、フォーム、属性など)を定義しています。
formFlagPresent format = 0x19
の行は、formFlagPresent
という新しい定数を定義し、その値を0x19
に設定しています。この0x19
は、DWARFv4仕様でDW_FORM_flag_present
に割り当てられている公式な値です。これにより、GoのコードがDWARFデータストリームからこの値を見つけたときに、それがDW_FORM_flag_present
であることを認識できるようになります。
src/pkg/debug/dwarf/entry.go
このファイルには、DWARFエントリ(DIE)を解析し、その属性を読み取るためのロジックが含まれています。buf
構造体のentry
メソッドは、DWARFのバイトストリームからDIEを読み取り、その属性を解析する主要な関数です。
変更箇所は、switch
文の中に新しいcase formFlagPresent:
ブロックが追加された点です。
case formFlag:
: 既存のDW_FORM_flag
を処理する部分です。ここでは、1バイトを読み込み、それが1であればtrue
、そうでなければfalse
としてval
に設定します。case formFlagPresent:
: 新しく追加された部分です。val = true
: ここが重要なポイントです。DW_FORM_flag_present
の場合、属性値はデータストリームにエンコードされていないため、何も読み込む必要がありません。属性が存在すること自体が「真」を意味するため、val
は直接true
に設定されます。- コメント: 「The attribute is implicitly indicated as present, and no value is encoded in the debugging information entry itself.」このコメントは、
DW_FORM_flag_present
の動作原理を明確に説明しており、属性が存在するだけでその値が真であることを示しています。
この変更により、debug/dwarf
パッケージはDWARFv4で導入されたDW_FORM_flag_present
形式の属性を正しくデコードし、Goのプログラム内でブール値として利用できるようになります。
関連リンク
- DWARF Standard: DWARFの公式仕様書は、DWARFのウェブサイトで公開されています。このコミットで参照されているのはDWARFv4のPDFです。
- Go Issue #4829: このコミットが解決したGoのイシュートラッカーのエントリです。
- https://code.google.com/p/go/issues/detail?id=4829 (古いGoogle Codeのリンクですが、現在はGitHubに移行しています)
- Go CL 7354043: このコミットに対応するGoのコードレビューシステム(Gerrit)のチェンジリストです。
参考にした情報源リンク
- DWARF Debugging Information Format Version 4 (特にセクション 7.5.4 "Attribute Forms" を参照)
- Go Issue Tracker (GitHub) (Goのイシュートラッカーの現在の場所)
- Go Code Review (Gerrit) (Goのコードレビューシステムの現在の場所)
- Wikipedia: DWARF
- GCC DWARF Debugging Information (DWARFに関する一般的な情報)
- LLVM DWARF Documentation (DWARFに関する一般的な情報)