[インデックス 17960] ファイルの概要
このコミットは、Go言語のツールチェインにおけるアセンブラ(cmd/5a
, cmd/6a
, cmd/8a
)に関連する修正です。具体的には、Yacc/Bisonの文法定義ファイルである.y
ファイル内で使用されている型名LAddr
が、以前のグローバルなリネーム作業でAddr
に更新されずに残っていた問題を修正しています。これにより、生成されるy.tab.c
およびy.tab.h
ファイルとの整合性が失われ、ビルドプロセスにおいて問題を引き起こす可能性がありました。
コミット
commit 426b48a77522c0e411cf328372bcfaae3dc7bcc9
Author: Russ Cox <rsc@golang.org>
Date: Wed Dec 11 12:11:37 2013 -0500
cmd/5a, cmd/6a, cmd/8a: fix .y files to match y.tab.[ch]
When I renamed LAddr back to Addr (before sending the
original linker CLs), I missed the .y files in my global substitute.
Since the .y files are only processed when running make in
one of those directories (not during all.bash), they were
behind the generated files.
R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/40770044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/426b48a77522c0e411cf328372bcfaae3dc7bcc9
元コミット内容
このコミットの元々の内容は、Go言語のリンカ関連の変更において、LAddr
という型名をAddr
にリネームした際に、一部のファイル、特にYacc/Bisonの文法定義ファイル(.y
ファイル)での置換が漏れていたことを修正するものです。コミットメッセージによると、この見落としは、.y
ファイルが特定のディレクトリでmake
を実行したときにのみ処理され、all.bash
のような全体ビルドスクリプトでは直接処理されないため、生成されたファイル(y.tab.c
, y.tab.h
)との間に不整合が生じていたことが原因です。
変更の背景
Go言語のコンパイラおよびアセンブラは、様々なアーキテクチャをサポートするために、それぞれに対応するツールチェインを持っています。cmd/5a
はARMアーキテクチャ用のアセンブラ、cmd/6a
はx86-64アーキテクチャ用のアセンブラ、cmd/8a
はARM64またはx86アーキテクチャ用のアセンブラ(文脈により異なるが、この時期は主にx86)を指します。
これらのアセンブラは、アセンブリ言語の構文解析にYacc/Bisonを使用しています。Yacc(Yet Another Compiler Compiler)やBisonは、文法定義ファイル(通常.y
拡張子を持つ)からC言語のパーサコード(y.tab.c
やy.tab.h
など)を生成するツールです。
コミットメッセージにある「LAddr back to Addr」という記述は、Go言語のリンカやアセンブラ内部でアドレスを表現するためのデータ構造または型名が、一度LAddr
と命名された後、何らかの理由で元のAddr
に戻されたことを示唆しています。このような大規模なリネーム作業では、コードベース全体にわたる変更が必要となり、手動または自動の置換ツールが使用されます。しかし、特定のビルドプロセスや依存関係を持つファイル(この場合は.y
ファイル)では、その変更が適切に反映されないことがあります。
このコミットの背景にある問題は、.y
ファイル内のLAddr
がAddr
に更新されなかったために、Yacc/Bisonが生成するC言語のヘッダファイルやソースファイル(y.tab.h
, y.tab.c
)と、.y
ファイル自体との間で型定義の不一致が生じたことです。これにより、アセンブラのビルド時にコンパイルエラーや予期せぬ動作が発生する可能性がありました。特に、.y
ファイルがall.bash
のようなトップレベルのビルドスクリプトではなく、各アセンブラディレクトリ内でのmake
実行時にのみ処理されるという特性が、この不整合が発覚しにくかった原因として挙げられています。
前提知識の解説
このコミットを理解するためには、以下の技術的知識が役立ちます。
- Go言語のツールチェイン: Go言語は、ソースコードをコンパイルして実行可能ファイルを生成するための一連のツール(コンパイラ、アセンブラ、リンカなど)を提供しています。これらはGoのソースコードと共に配布され、
cmd/
ディレクトリ以下に配置されています。cmd/5a
: GoのARMアーキテクチャ用アセンブラ。cmd/6a
: Goのx86-64アーキテクチャ用アセンブラ。cmd/8a
: GoのARM64またはx86アーキテクチャ用アセンブラ。
- アセンブラ: アセンブリ言語で書かれたプログラムを機械語に変換するプログラムです。Goのアセンブラは、Goのコンパイラが生成する中間表現を最終的な機械語に変換する役割を担います。
- Yacc/Bison: Yacc (Yet Another Compiler Compiler) は、文法定義から構文解析器(パーサ)を生成するプログラムです。BisonはGNU版のYaccで、より高機能です。
.y
ファイル: Yacc/Bisonの文法定義ファイルです。BNF(Backus-Naur Form)に似た形式で文法規則と、各規則が認識されたときに実行されるアクション(C言語のコード)を記述します。y.tab.c
/y.tab.h
:.y
ファイルをYacc/Bisonで処理すると生成されるC言語のソースファイルとヘッダファイルです。これらには、定義された文法に基づいて入力ストリームを解析するためのコードが含まれています。
- リンカ: コンパイラやアセンブラによって生成されたオブジェクトファイル(機械語コードやデータを含む)を結合し、最終的な実行可能ファイルを生成するプログラムです。リンカは、異なるオブジェクトファイル間の参照(関数呼び出しや変数アクセスなど)を解決し、必要なライブラリをリンクします。
- 型定義とスコープ: プログラミング言語において、型はデータの種類を定義し、変数がどのような値を保持できるかを決定します。型名の変更は、その型を使用しているすべての箇所で更新される必要があります。C言語のようなコンパイル言語では、型定義の不一致はコンパイルエラーを引き起こします。
技術的詳細
このコミットの技術的な核心は、Goツールチェインのビルドプロセスにおける依存関係と、Yacc/Bisonによって生成されるコードの特性にあります。
Goのアセンブラは、アセンブリ言語のソースコードを解析するために、Yacc/Bisonで定義された文法を使用しています。.y
ファイルは、アセンブリ言語の命令やオペランドの構文を定義し、それらがどのように解析されるべきかを記述します。Yacc/Bisonは、この.y
ファイルを読み込み、C言語のパーサコード(y.tab.c
)と、パーサが使用するトークンや型定義を含むヘッダファイル(y.tab.h
)を生成します。
問題は、Goのリンカ関連のコードベース全体でLAddr
という型名がAddr
にリネームされた際に、この変更が.y
ファイルに適用されなかったことです。通常、大規模なリネームは、IDEのグローバル置換機能やスクリプトを使って行われますが、特定のファイルタイプやビルドプロセスの特殊性により、一部のファイルが見落とされることがあります。
このケースでは、.y
ファイルは直接Goのビルドシステム(all.bash
)によって処理されるのではなく、各アセンブラのディレクトリ内でmake
コマンドが実行されたときに、Yacc/Bisonによって処理されます。つまり、y.tab.c
やy.tab.h
は、.y
ファイルから生成されるため、.y
ファイルが古い型名LAddr
を保持していると、生成されるy.tab.h
にもLAddr
の定義が含まれることになります。
しかし、Goのリンカや他の関連コードはすでにAddr
という新しい型名を使用しているため、y.tab.h
が提供するLAddr
と、他のコードが期待するAddr
との間で型定義の不一致が発生します。これはC言語のコンパイル時において、未定義の型や型の不一致としてエラー(例: error: unknown type name 'LAddr'
)を引き起こします。
このコミットは、この不整合を解消するために、src/cmd/5a/a.y
、src/cmd/6a/a.y
、src/cmd/8a/a.y
の各ファイル内で、LAddr
と記述されている箇所をAddr
に修正しています。これにより、Yacc/Bisonがこれらのファイルを処理してy.tab.c
やy.tab.h
を生成する際に、正しい型名Addr
が使用されるようになり、ツールチェイン全体の整合性が保たれます。
コアとなるコードの変更箇所
変更は以下の3つのファイルにわたります。
src/cmd/5a/a.y
(ARMアセンブラの文法定義ファイル)src/cmd/6a/a.y
(x86-64アセンブラの文法定義ファイル)src/cmd/8a/a.y
(ARM64/x86アセンブラの文法定義ファイル)
各ファイルにおいて、LAddr
という文字列がAddr
に置換されています。
src/cmd/5a/a.y
の変更点:
--- a/src/cmd/5a/a.y
+++ b/src/cmd/5a/a.y
@@ -41,7 +41,7 @@
int32 lval;
double dval;
char sval[8];
- LAddr addr;
+ Addr addr;
}
%left '|'
%left '^'
@@ -175,7 +175,7 @@ inst:
*/
| LTYPE8 cond ioreg ',' '[' reglist ']'
{
- LAddr g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
@@ -184,7 +184,7 @@ inst:
}
| LTYPE8 cond '[' reglist ']' ',' ioreg
{
- LAddr g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
@@ -279,7 +279,7 @@ inst:
*/
| LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
{
- LAddr g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
src/cmd/6a/a.y
の変更点:
--- a/src/cmd/6a/a.y
+++ b/src/cmd/6a/a.y
@@ -40,7 +40,7 @@
vlong lval;
double dval;
char sval[8];
- LAddr addr;
+ Addr addr;
Addr2 addr2;
}
%left '|'
src/cmd/8a/a.y
の変更点:
--- a/src/cmd/8a/a.y
+++ b/src/cmd/8a/a.y
@@ -44,7 +44,7 @@
} con2;
double dval;
char sval[8];
- LAddr addr;
+ Addr addr;
Addr2 addr2;
}
%left '|'
コアとなるコードの解説
これらの変更は非常にシンプルで、LAddr
という文字列をAddr
に置き換えるだけです。
Yacc/Bisonの文法定義ファイル(.y
)では、%union
ディレクティブを使って、パーサが扱う様々な値の型を定義します。このコミットでは、%union
ブロック内で定義されているaddr
というフィールドの型がLAddr
からAddr
に変更されています。
例えば、src/cmd/5a/a.y
の以下の部分が該当します。
%union{
int32 lval;
double dval;
char sval[8];
LAddr addr; // ここが変更対象
}
このaddr
フィールドは、アセンブリ命令のオペランドとしてアドレス値を扱う際に使用される共用体メンバーです。LAddr
からAddr
への変更は、このアドレス型がGoのリンカや他のツールチェインコンポーネントで統一的にAddr
として扱われるようにするためのものです。
また、inst:
ルール内のアクションブロック(C言語のコードが記述されている部分)でも、LAddr g;
というローカル変数の宣言がAddr g;
に変更されています。これは、パーサが構文解析中に一時的にアドレス値を保持するために使用する変数であり、型定義の変更に合わせて修正されています。
これらの変更は、Goツールチェインの内部的な型システムの一貫性を保ち、ビルド時のコンパイルエラーを防ぐための、クリーンアップかつ重要な修正と言えます。
関連リンク
- Go言語の公式リポジトリ: https://github.com/golang/go
- Go言語のIssueトラッカー (このコミットに関連するCLのリンク): https://golang.org/cl/40770044
参考にした情報源リンク
- Yacc/Bisonのドキュメント (一般的な情報):
- GNU Bison Manual: https://www.gnu.org/software/bison/manual/
- Go言語のツールチェインに関するドキュメント (一般的な情報):
- Go Command Documentation: https://pkg.go.dev/cmd
- The Go Programming Language Specification: https://go.dev/ref/spec
- Go言語のソースコード (コミット内容の理解のため):
src/cmd/5a/a.y
(Goリポジトリ内)src/cmd/6a/a.y
(Goリポジトリ内)src/cmd/8a/a.y
(Goリポジトリ内)
- Go言語のリンカに関する情報 (一般的な情報):
- Go linker source code (e.g.,
src/cmd/link/internal/ld/
) - "Go's linker" by Russ Cox (blog post or presentation if available) - このコミットの作者であるRuss Cox氏によるリンカに関する解説は、背景理解に非常に役立つ可能性がありますが、特定の記事への直接リンクは現時点では特定できません。
- Go linker source code (e.g.,