[インデックス 15917] ファイルの概要
このコミットは、Go言語のツールチェインの一部であるリンカ (cmd/5l
, cmd/6l
, cmd/8l
) のヘッダーファイル (l.h
) から、もはや存在しない、または使用されていない変数の宣言を削除するものです。これにより、コードベースのクリーンアップと保守性の向上が図られています。
コミット
cmd/5l, cmd/6l, cmd/8l: remove declaration on non-existent variables.
R=golang-dev, minux.ma
CC=golang-dev
https://golang.org/cl/7985043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a3c2d62a9ab518ed6098375d4df91e0521c86026
元コミット内容
commit a3c2d62a9ab518ed6098375d4df91e0521c86026
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date: Sun Mar 24 08:55:08 2013 +0100
cmd/5l, cmd/6l, cmd/8l: remove declaration on non-existent variables.
R=golang-dev, minux.ma
CC=golang-dev
https://golang.org/cl/7985043
変更の背景
この変更の背景には、Go言語のツールチェイン、特にリンカのコードベースの継続的な改善と保守があります。ソフトウェア開発において、時間の経過とともにコードは進化し、機能の追加、削除、リファクタリングが行われます。その過程で、以前は必要だった変数や関数が不要になることがあります。しかし、それらの宣言がコードベースに残されたままだと、以下のような問題を引き起こす可能性があります。
- コードの肥大化: 不要な宣言が残ることで、コードベースが不必要に大きくなります。
- 可読性の低下: 開発者がコードを読んだ際に、宣言されているがどこにも使われていない変数を見て混乱する可能性があります。
- 保守性の低下: 不要なコードは、将来の変更やデバッグの際に誤って影響を与えたり、考慮すべき要素を増やしたりする原因となります。
- コンパイラ/リンカの警告: 一部のコンパイラやリンカは、宣言されているが使用されていない変数に対して警告を発することがあり、ビルドプロセスのノイズとなることがあります。
このコミットは、これらの問題を解決するために、Goリンカのヘッダーファイルから「存在しない変数」(つまり、もはやコードのどこからも参照されていない変数)の宣言を削除することを目的としています。これは典型的なコードクリーンアップ作業であり、コードベースの健全性を維持し、将来の開発を容易にするために重要です。
前提知識の解説
このコミットを理解するためには、以下の前提知識が役立ちます。
Go言語のツールチェインとリンカ
Go言語は、go build
コマンドを通じてソースコードをコンパイルし、実行可能なバイナリを生成します。このプロセスには、コンパイラ、アセンブラ、そしてリンカといった複数のツールが関与します。
- コンパイラ: Goのソースコードをアセンブリコードに変換します。
- アセンブラ: アセンブリコードをオブジェクトファイル(機械語)に変換します。
- リンカ: 複数のオブジェクトファイルやライブラリを結合し、最終的な実行可能バイナリを生成します。リンカは、関数呼び出しや変数参照を解決し、メモリレイアウトを決定する重要な役割を担います。
cmd/5l
, cmd/6l
, cmd/8l
これらは、Go言語の初期のツールチェインにおける異なるアーキテクチャ向けのリンカを指します。
cmd/5l
: Plan 95l
リンカに由来し、ARMアーキテクチャ(GOARCH=arm
)向けのリンカです。cmd/6l
: Plan 96l
リンカに由来し、AMD64アーキテクチャ(GOARCH=amd64
)向けのリンカです。cmd/8l
: Plan 98l
リンカに由来し、386アーキテクチャ(GOARCH=386
)向けのリンカです。
これらのリンカは、Goのクロスコンパイル能力を支える重要なコンポーネントでした。現在では、Goのリンカはより統合された形で提供されていますが、当時のコードベースではアーキテクチャごとに独立したリンカが存在していました。
l.h
ファイル
Goのツールチェインのソースコードにおいて、l.h
のようなファイルは、リンカの内部で使用される共通のデータ構造、マクロ、および外部変数(EXTERN
キーワードで宣言されたもの)の宣言を含むヘッダーファイルとして機能します。C言語の慣習に従い、これらのヘッダーファイルは、複数のソースファイル間で共有される定義を提供します。
EXTERN
キーワード
C言語の文脈では、EXTERN
は通常、extern
キーワードのエイリアスまたはマクロとして使用されます。extern
キーワードは、変数が現在のファイルではなく、別のファイルで定義されていることをコンパイラに伝えます。これにより、複数のソースファイルが同じグローバル変数にアクセスできるようになります。このコミットでは、EXTERN
で宣言された変数が、もはやどこにも定義されていないか、使用されていない状態になっていたため、その宣言が削除されました。
ELF (Executable and Linkable Format)
ELFは、Unix系システムで広く使用されている実行可能ファイル、オブジェクトコード、共有ライブラリ、およびコアダンプファイルの標準ファイル形式です。リンカは、ELF形式のファイルを生成する際に、セクション(コード、データなど)のサイズやオフセットといった情報を管理します。コミットで削除された elfdatsize
や elftextsh
といった変数は、ELFファイルのデータセクションやテキストセクションのサイズ、または関連する情報を取り扱うために使用されていた可能性があります。
技術的詳細
このコミットは、Goリンカの内部構造における不要な依存関係や宣言を解消するものです。削除された変数は、過去のリンカの設計や機能に関連していた可能性がありますが、その後のリファクタリングや機能変更によって不要になったと考えられます。
具体的に削除された変数は以下の通りです。
int32 elfdatsize;
(src/cmd/5l/l.h, src/cmd/8l/l.h)vlong elfdatsize;
(src/cmd/6l/l.h)int32 casepc;
(src/cmd/8l/l.h)int elftextsh;
(src/cmd/8l/l.h)
これらの変数は、それぞれ異なるリンカのヘッダーファイルから削除されています。
elfdatsize
: これは、ELFファイルのデータセクションのサイズに関連する変数であると推測されます。int32
とvlong
の違いは、アーキテクチャやリンカのバージョンによってデータ型の選択が異なっていたことを示唆しています。不要になった理由は、データセクションのサイズ管理方法が変更されたか、あるいはこの変数が特定の最適化やデバッグ機能のために一時的に導入されたが、その後廃止されたためかもしれません。casepc
:src/cmd/8l/l.h
から削除されたcasepc
は、"case program counter" の略である可能性があります。これは、特定の命令やコードブロックの処理に関連するプログラムカウンタの値を保持するために使用されていたかもしれません。リンカの命令処理ロジックの変更により、この変数が不要になったと考えられます。elftextsh
:src/cmd/8l/l.h
から削除されたelftextsh
は、"ELF text section header" の略である可能性があります。これは、ELFファイルのテキストセクション(実行可能コードを含むセクション)のヘッダー情報に関連する変数であったと推測されます。テキストセクションの管理方法の変更や、より抽象化されたデータ構造への移行により、この変数が直接必要なくなった可能性があります。
これらの変数の削除は、リンカのコードがより簡潔になり、不要なグローバル状態が減ることを意味します。これは、コードの理解を容易にし、将来の変更における副作用のリスクを低減します。また、コンパイラがこれらの宣言を処理する必要がなくなるため、わずかながらビルド時間の短縮にも寄与する可能性があります。
コアとなるコードの変更箇所
このコミットでは、以下の3つのファイルから合計5行のコードが削除されています。
src/cmd/5l/l.h
--- a/src/cmd/5l/l.h
+++ b/src/cmd/5l/l.h
@@ -299,7 +299,6 @@ EXTERN Auto* curhist;
EXTERN Prog* curp;
EXTERN Sym* cursym;
EXTERN Sym* datap;
-EXTERN int32 elfdatsize;
EXTERN int debug[128];
EXTERN Sym* etextp;
EXTERN char* noname;
src/cmd/6l/l.h
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -336,7 +336,6 @@ EXTERN Auto* curhist;
EXTERN Prog* curp;
EXTERN Sym* cursym;
EXTERN Sym* datap;
-EXTERN vlong elfdatsize;
EXTERN int debug[128];
EXTERN char literal[32];
EXTERN Sym* textp;
src/cmd/8l/l.h
--- a/src/cmd/8l/l.h
+++ b/cmd/8l/l.h
@@ -286,14 +286,12 @@ EXTERN int32 INITTEXT;
EXTERN int32 INITDAT;
EXTERN char* INITENTRY; /* entry point */
EXTERN char* LIBINITENTRY; /* shared library entry point */
-EXTERN int32 casepc;
EXTERN char* pcstr;
EXTERN Auto* curauto;
EXTERN Auto* curhist;
EXTERN Prog* curp;
EXTERN Sym* cursym;
EXTERN Sym* datap;
-EXTERN int32 elfdatsize;
EXTERN int debug[128];
EXTERN char literal[32];
EXTERN Sym* etextp;
@@ -319,7 +317,6 @@ EXTERN int dtype;
EXTERN int tlsoffset;
EXTERN Sym* adrgotype; // type symbol on last Adr read
EXTERN Sym* fromgotype; // type symbol on last p->from read
-EXTERN int elftextsh;
extern Optab optab[];
extern char* anames[];
コアとなるコードの解説
削除された各行は、EXTERN
キーワードで始まる変数の宣言です。
EXTERN int32 elfdatsize;
(src/cmd/5l/l.h)EXTERN vlong elfdatsize;
(src/cmd/6l/l.h)- これらは、それぞれ32ビット整数型 (
int32
) と64ビット整数型 (vlong
、Goの初期のコードベースで使われていた可能性のある型) のelfdatsize
という変数を外部変数として宣言していました。elfdatsize
は、ELFバイナリのデータセクションのサイズを保持するために使われていたと推測されます。異なるリンカ (5l
と6l
) で異なる型が使われていたのは、それぞれのアーキテクチャの特性やリンカの実装の違いによるものと考えられます。
- これらは、それぞれ32ビット整数型 (
EXTERN int32 casepc;
(src/cmd/8l/l.h)- これは、32ビット整数型
casepc
を外部変数として宣言していました。casepc
は、プログラムカウンタに関連する何らかの値を保持していた可能性があり、特に条件分岐やジャンプ命令の処理に関連していたかもしれません。
- これは、32ビット整数型
EXTERN int32 elfdatsize;
(src/cmd/8l/l.h)src/cmd/5l/l.h
と同様に、src/cmd/8l/l.h
でもelfdatsize
が宣言されていました。
EXTERN int elftextsh;
(src/cmd/8l/l.h)- これは、整数型
elftextsh
を外部変数として宣言していました。elftextsh
は、ELFバイナリのテキストセクション(コードセクション)のヘッダー情報に関連するインデックスやオフセットを保持していたと推測されます。
- これは、整数型
これらの変数が削除されたのは、リンカの内部ロジックが変更され、これらの変数がもはや必要なくなったためです。例えば、ELFファイルの構造を扱うための新しい、より抽象化されたデータ構造が導入されたり、特定の最適化やデバッグ機能が削除されたりした可能性があります。これにより、これらの変数の宣言が「存在しない変数」となり、コードベースからクリーンアップされました。
関連リンク
- Go言語の公式ウェブサイト: https://go.dev/
- Go言語のツールチェインに関するドキュメント (Go 1.0.3): https://go.dev/doc/go1.0.3 (当時のGoのバージョンに近い情報)
- Go言語のソースコードリポジトリ: https://github.com/golang/go
参考にした情報源リンク
- Go CL 7985043: https://golang.org/cl/7985043
- ELFファイルフォーマットに関する一般的な情報 (Wikipediaなど): https://ja.wikipedia.org/wiki/Executable_and_Linkable_Format
- C言語の
extern
キーワードに関する情報: https://www.geeksforgeeks.org/understanding-extern-keyword-in-c/ - Go言語の初期のリンカに関する議論やドキュメント (当時の情報源を特定するのは困難な場合がありますが、GoのIssueトラッカーやメーリングリストのアーカイブが参考になることがあります)
- Plan 9 from Bell Labs: https://9p.io/plan9/ (GoのツールチェインがPlan 9の設計思想に影響を受けているため)
- Goのリンカの進化に関する情報 (例: Go 1.5以降のコンパイラとリンカの統合): https://go.dev/blog/go15compiler (このコミットの時点より後の情報ですが、リンカの進化を理解する上で参考になります)