[インデックス 16879] ファイルの概要
このコミットは、Goコンパイラの5c
(Plan 9 CコンパイラをベースとしたGoの初期のコンパイラの一つ)におけるバグ修正に関するものです。具体的には、AFUNCDATA
(実際にはFUNCDATA
の誤記である可能性が高い)が存在する場合のプログラムカウンタ(PC)の再計算ロジックの不具合を修正し、それによってARMアーキテクチャでのビルドが壊れる問題(CL 11683043によって引き起こされたもの)を解決しています。
コミット
commit de6da4a8bdce935ba71f585bb458272cc781dd9a
Author: Keith Randall <khr@golang.org>
Date: Thu Jul 25 17:40:29 2013 -0700
5c: fix pc recalculation in the presence of AFUNCDATA
This makes CL 11683043 not break arm anymore.
R=golang-dev, bradfitz, dave
CC=golang-dev
https://golang.org/cl/11888043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/de6da4a8bdce935ba71f585bb458272cc781dd9a
元コミット内容
diff --git a/src/cmd/5c/reg.c b/src/cmd/5c/reg.c
index 030b0c327e..25bfc58222 100644
--- a/src/cmd/5c/reg.c
+++ b/src/cmd/5c/reg.c
@@ -461,6 +461,7 @@ brk:
case AGLOBL:
case ANAME:
case ASIGNAME:
+ case AFUNCDATA:
break;
}
}
変更の背景
このコミットは、Goコンパイラの5c
が生成するコードにおいて、AFUNCDATA
(おそらくFUNCDATA
の誤記)という特殊なデータが存在する場合に、プログラムカウンタ(PC)の再計算が正しく行われないというバグを修正するために導入されました。このバグは、以前の変更(CL 11683043)によってARMアーキテクチャ上でGoのビルドを壊すという具体的な問題を引き起こしていました。
Goのコンパイラとランタイムは、デバッグ情報、プロファイリング、ガベージコレクション(GC)などの目的で、実行中のコードのPC値とソースコード上の位置を正確にマッピングする必要があります。このマッピングが正しく行われないと、デバッガが誤った行番号を表示したり、プロファイラが不正確なパフォーマンスデータを提供したり、最悪の場合、GCがポインタを正しく識別できずにメモリ破損やクラッシュを引き起こす可能性があります。
特にARMのような特定のアーキテクチャで問題が発生したということは、PCの計算ロジックがアーキテクチャ固有の特性(例えば、命令セットの長さやアラインメントなど)に依存しているか、またはAFUNCDATA
の配置がARMのコード生成に特有の影響を与えていた可能性を示唆しています。
前提知識の解説
1. Goコンパイラと5c
Go言語の初期のコンパイラは、Plan 9オペレーティングシステム由来のツールチェインをベースにしていました。5c
はその一つで、ARMアーキテクチャ向けのC言語コンパイラを指します(5
はARMのPlan 9におけるアーキテクチャコード)。Go 1.5以降、Goコンパイラ自体がGo言語で再実装され、5c
のようなPlan 9由来のツールへの依存は大幅に減少しましたが、このコミットが作成された2013年時点では、まだGoのビルドプロセスにおいて重要な役割を担っていました。
2. プログラムカウンタ(PC)
プログラムカウンタ(Program Counter, PC)は、CPUが次に実行する命令のアドレスを保持するレジスタです。Goのランタイムやデバッグツールは、実行中のPC値から、それがどの関数、どのファイル、どの行のコードに対応するかを特定します。これは、スタックトレースの生成、デバッガでのステップ実行、プロファイリングなど、多くの低レベルな操作で不可欠です。
3. PCの再計算(PC Recalculation)
コンパイラは、ソースコードを機械語に変換する際に、様々な最適化を適用します。例えば、関数インライン化(呼び出し元のコードに呼び出される関数の本体を直接埋め込む)や、デッドコードの削除、命令の並べ替えなどです。これらの最適化は、元のソースコードの構造と生成された機械語のPC値との間に複雑な関係を生み出します。
「PCの再計算」とは、これらの最適化が適用された後でも、実行時のPC値から元のソースコードの正確な位置(ファイル名、行番号、関数名など)を導き出すプロセスを指します。これは、コンパイラが生成するデバッグ情報やメタデータ(例えば、GoにおけるPCDATA
やFUNCDATA
)を利用して行われます。このプロセスが正しく機能しないと、デバッグやプロファイリングが困難になります。
4. FUNCDATA
(Function Data)
FUNCDATA
は、Goコンパイラが生成するバイナリに埋め込まれるメタデータの一種です。これは主にガベージコレクション(GC)のために使用されます。GoのGCは、スタックやヒープ上のポインタを正確に識別し、到達可能なオブジェクトをマークする必要があります。FUNCDATA
は、特定の関数のスタックフレーム内でどの位置にポインタが存在するか(ポインタマップ)などの情報を提供し、GCが安全かつ効率的に動作することを可能にします。
コミットメッセージにあるAFUNCDATA
は、おそらくFUNCDATA
の誤記、またはFUNCDATA
に関連する特定の内部的なデータ構造やアブストラクションを指していると考えられます。アセンブリ言語で書かれた関数では、開発者が明示的にFUNCDATA
ディレクティブを使用してこの情報を提供する必要があります。
5. CL (Change List)
Goプロジェクトでは、コード変更は「Change List (CL)」として管理されます。これは、Gerritというコードレビューシステムで使われる用語で、一連のコミットをまとめたものです。コミットメッセージに記載されているCL 11683043
は、このコミットが修正しようとしている問題を引き起こした、以前の特定の変更セットを指します。
技術的詳細
このコミットは、src/cmd/5c/reg.c
ファイル内のbrk:
ラベルが付いたコードブロックに、AFUNCDATA
というケースを追加しています。このファイルは、5c
コンパイラのレジスタ割り当てやコード生成に関連する部分であると推測されます。
brk:
ラベルの周辺のコードは、おそらく特定の種類のオペランド(命令の引数)を処理するロジックの一部です。既存のケースには、AGLOBL
(グローバル変数)、ANAME
(名前付きエンティティ)、ASIGNAME
(シグネチャ名)などがあります。これらはすべて、コンパイラがシンボルやデータ構造を扱う際に遭遇する可能性のあるオペランドの種類です。
AFUNCDATA
がこのリストに追加されたということは、コンパイラがPCの再計算を行う際に、AFUNCDATA
タイプのオペランドを特別に扱う必要があることを示唆しています。具体的には、AFUNCDATA
がPCの計算に影響を与えるような形でコード内に存在する場合、その存在を認識し、PCのオフセットやアラインメントを適切に調整する必要があったと考えられます。
PCの再計算が壊れるシナリオとしては、以下のような可能性が考えられます。
- 不正確なオフセット計算:
AFUNCDATA
がコードセクション内に挿入される際、そのサイズや配置がPCの計算ロジックに考慮されていなかったため、後続の命令のPC値がずれてしまった。 - ポインタ情報の欠落/誤読:
AFUNCDATA
がGCのためのポインタ情報を含んでいる場合、PCの再計算ロジックがこのデータを正しく解釈できず、デバッグ情報やGCのメタデータとの整合性が失われた。 - アーキテクチャ固有の挙動: ARMアーキテクチャでは、命令のエンコーディングやメモリのアラインメント要件が他のアーキテクチャと異なるため、
AFUNCDATA
の処理が特に問題を引き起こしやすかった。
この修正は、AFUNCDATA
ケースに対してbreak;
文を実行するだけなので、これは「何もしない」ことを意味します。これは、AFUNCDATA
がPCの再計算ロジックにおいて、特別な処理を必要とせず、単にスキップされるべきオペランドであることを示唆している可能性があります。つまり、以前はAFUNCDATA
が未知のオペランドとして扱われ、それがPCの計算を狂わせていたが、この修正により、AFUNCDATA
はPC計算に影響を与えない「安全な」要素として認識されるようになった、ということです。
コアとなるコードの変更箇所
変更はsrc/cmd/5c/reg.c
ファイルの一箇所のみです。
--- a/src/cmd/5c/reg.c
+++ b/src/cmd/5c/reg.c
@@ -461,6 +461,7 @@ brk:
case AGLOBL:
case ANAME:
case ASIGNAME:
+ case AFUNCDATA:
break;
}
}
コアとなるコードの解説
このコードスニペットは、C言語のswitch
文の一部であり、brk:
というラベルが付いたブロック内にあります。case
文のリストは、Goコンパイラの5c
が処理する様々な種類のオペランド(A
で始まる定数はおそらくenum
で定義されたオペランドの種類を表す)を示しています。
追加された行 case AFUNCDATA:
は、コンパイラがAFUNCDATA
タイプのオペランドに遭遇した場合の処理を定義しています。その直後に続く break;
は、このケースにマッチした場合に、現在のswitch
文から抜け出すことを意味します。
この修正のポイントは、AFUNCDATA
が既存のAGLOBL
、ANAME
、ASIGNAME
と同様に、PCの再計算ロジックにおいて特別な処理を必要としない、あるいは無視しても安全なオペランドとして明示的に認識された点です。以前は、AFUNCDATA
がこのswitch
文のどのcase
にもマッチしなかったため、おそらくデフォルトの処理(またはフォールスルー)が実行され、それがPCの計算を誤らせていたと考えられます。この修正により、AFUNCDATA
が正しく識別され、PCの計算に悪影響を与えないように処理されるようになりました。
関連リンク
- Go言語の公式ウェブサイト: https://golang.org/
- Goのソースコードリポジトリ (GitHub): https://github.com/golang/go
- GoのCL (Change List) システム (Gerrit): https://go.dev/cl/ (コミットメッセージに記載されているCL 11888043へのリンク)
参考にした情報源リンク
- Go compiler 5c:
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHcIze9GXfBXfl9jPmXB-MNuVG2Egi9rgOtDdM4qOP-5txeLAOubifUoiw5iEMUxZR_GwUVd3tFeE1ErHVRYUIyGqG3oavjYIwGifKggBu7VPNgvDp0IrZPlFNXeKuHmCKCuy5WbYzjvELQ8n-jtYmY1ljWB_LY
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQESVi0Pki61K3vOsQ92uuc1agY67gpROvFsjrPNxQwWl2rlCb-bCIN-93IN0P9yc-J_ZmTJnrKIORGmDNl8tzvnsiZ61E_GOeMX3UdduEDzu7gxmvI7bzl-lf8JuB8LLFnIJLUsY6HPGKTCGDRaFGjQjCdeYgdJcqyLAOEg3uBJAl_G1YbtPwjcLPkoMYGlVM6wFeAiuo33T_AGrw==
- Go FUNCDATA:
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQER-XZ6nG8RZ0cz27CmaMk83EOzQYy9lCqLlt7DZkFBoKDSfuFnUHgPcI31M8U3zLVXG3RQeGKaXgk5wHH1xJs2HjkJdlAAUaL07QS-r8VR7GKSJkaNJ5nRuI8sp97AG_9uuxfqQKXG71WkPUdq6UO6U92lQwKwg2AoQ8TTuTSpgoUsusUH03YsK3FFzTqSFvrqZTk=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEXbbbTc1xgpBpnTb56I27C7FPDljRy5sZiFTxz7S9bzN1HEbWX8XLcUvFCMYj5ismaXi2acK0tD8OCR5FWFaYaEOK5yG5Z5QfMlsqU5dQofraCgK_nsE0o0Jci6mLLxzchPYxyd_wAZc4AcAvzJ2I4P7dIUXghnblp_ovP_OE9p-CPJLis25NorB42CXgfUsbhkT0
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHaVlp9DXk1R1IxCjac8tf63NHuo2mrazWskgjEW9r89Ig80JahEtHVjjiwo9Dw5qOc0iUH19d77cMUNbujLe-cuebtFKwbLxq8N6tRWFuy1S1G6u47zYiOE64N3QIuUSf3r4ux2n6Slzt82cdUgvuWzp6g==
- Go pc recalculation compiler:
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEjdu9g9Am1NtkdzbHGSBA8Kq26RfiNPrXEjssWleRYAmBfcuEPxHHODT3si390OAo5krbx-rFLbvQMaQ2_KuXkaL_yulrxMJpKOPJ24Euyou1f6ELeASgC2DJfCzcBDPN7SFGrfZUFEkHyET5fJF-jyCSyMVnb4cg=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFU-_VIBz8xUQIzB8Cotu3evaCTym4XwaGdoWBSp2xT2AYsz5FjMwZSB97I1nf6GSRmkeq_Gw4ikh9El3bBbK4nyr7pUhY9jj8NtftGUP7a5rMPBx-LtrbEtz5KiMWO-hVyBLth
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHzqnWqR9wnj5-94JvrImoMpNzlO2_f9ewEw5NmsXzPvwicMPpoBYOlW8c_F9jgiKaCS5ATZON7FaoNPV9IpcKcUnD_abqMH3HgUfdDVfr5Vni7nMun_xDZlXyycQsWo4bQzTUZ4nExbLHDYlitMWCdDvB0jedbwK0d1OYlpFSPrjTlZ-zOSXHpS3uuwnc1D70kGDv1A6hS1HEkkkbA
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEovcFzHWMomxQ9DxoKfbOq14jwPDFpX1l_n_QFcSwhbbfwWy_B0slq0uOLVAkbvWFowgUcp3KsDOEcNUxY-1P9p5IHTDR7HQdCkicxLSu1I5kFsMyeHT8mgFnqWl2zRY_WiFLLbHRX9iYiOTE0qiatfBP3Diobgrspo1u961GOG3KvUKbGVlhf9XbRwPdkE8HAvHU6gKagxJfsf87bTYsDV8nou-ctL4geZEsTkJHyHRObupLYzg7Y
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG36E5u3EX5YcbMu3YuKEOago1Af4ysIzBtA7oxUsomd_0q7BT39nLKYO7MmxHLO3iaBqjzKxNzVCpt0dHQxg3TCyyG5Nr_Y81MG0eUgti93BE=