[インデックス 16961] ファイルの概要
このコミットは、Go言語のリンカー (cmd/ld
) における以前の変更 (CL 12193043 / cc5858966b08) を元に戻すものです。元の変更は、リンカーの冗長出力 (6l -v
) に pclntab
と funcdata
のサイズ情報を追加し、一部の冗長なメッセージをより詳細なデバッグレベル (-v -v
) に移動させることを目的としていました。しかし、この変更が「すべてのELFビルドを破壊する」という重大な問題を引き起こしたため、このコミットで元に戻されました。
コミット
commit b08d0c2c62c901b69637cb6f13af490c6feacbe6
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Wed Jul 31 15:31:43 2013 -0700
undo CL 12193043 / cc5858966b08
Breaks all ELF builds.
««« original CL description
cmd/ld: report pclntab, funcdata sizes in 6l -v output
Also move chatty recent additions to -v -v.
For what it's worth:
$ go build -o /dev/null -ldflags -v cmd/godoc
...
0.73 pclntab=1259976 bytes, funcdata total 79788 bytes
...
$
R=ken2
CC=cshapiro, golang-dev
https://golang.org/cl/12193043
»»»
R=rsc
CC=golang-dev
https://golang.org/cl/12202043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b08d0c2c62c901b69637cb6f13af490c6feacbe6
元コミット内容
このコミットは、以下の内容を持つ元のコミット (CL 12193043 / cc5858966b08) を元に戻すものです。
- 目的:
cmd/ld
(Goリンカー) の-v
(verbose) 出力にpclntab
とfuncdata
のサイズ情報を追加する。 - 詳細:
go build -ldflags -v
コマンドの出力に、pclntab
とfuncdata
の合計サイズが表示されるようになる。- リンカーのログ出力のうち、最近追加された「おしゃべりな」メッセージを、より詳細なデバッグレベル (
-v -v
またはdebug['v'] > 1
) に移動させる。
- 例:
go build -o /dev/null -ldflags -v cmd/godoc
の実行例が示されており、pclntab
とfuncdata total
のサイズが出力されることが示されている。
変更の背景
元のコミット (CL 12193043) は、Goリンカーの冗長出力に有用なデバッグ情報を追加することを意図していました。特に、pclntab
と funcdata
のサイズは、Goバイナリのサイズ分析や、ランタイムの内部構造を理解する上で役立つ情報です。しかし、この変更が実装された結果、「すべてのELFビルドを破壊する」という深刻なリグレッションが発生しました。ELF (Executable and Linkable Format) は、LinuxなどのUnix系システムで広く使用されている実行可能ファイル、オブジェクトコード、共有ライブラリの標準フォーマットです。このリグレッションは、GoプログラムがELF形式でビルドできなくなることを意味し、Goの利用可能性に大きな影響を与えるため、迅速に元に戻す必要がありました。
具体的な破壊の原因はコミットメッセージには明記されていませんが、pclntab
や funcdata
の処理方法の変更がELFフォーマットの仕様と衝突したか、リンカーがELFファイルを正しく生成できなくなった可能性が高いです。特に、funcdata_bytes
の計算と関連するシンボルの処理が、ELFのセクション配置やシンボル解決に影響を与えたことが考えられます。
前提知識の解説
このコミットを理解するためには、以下のGo言語の内部構造とツールチェインに関する知識が必要です。
-
Goリンカー (
cmd/ld
):- Goのビルドプロセスにおいて、コンパイルされたオブジェクトファイルを結合し、実行可能なバイナリを生成するツールです。
-v
フラグは、リンカーの動作に関する詳細な情報を出力するために使用されます。-v -v
(またはdebug['v'] > 1
) は、さらに詳細なデバッグ情報を表示します。
-
pclntab
(Program Counter Line Table):- Goのバイナリに含まれる重要なデータ構造の一つで、「プログラムカウンタ-行番号テーブル」の略です。
- 主に、スタックトレースの生成、プロファイリング、デバッグなどのランタイム機能で使用されます。
- 特定のプログラムカウンタ (PC) アドレスが、ソースコードのどのファイル、どの行に対応するかをマッピングする情報を含んでいます。
- Goの実行時エラーが発生した際に、人間が読める形式のスタックトレースを出力できるのは、この
pclntab
のおかげです。
-
funcdata
(Function Data):- Goのバイナリに含まれる、関数に関する追加のメタデータです。
- ガベージコレクション (GC) のために、各関数がスタック上に持つポインタの位置情報などを格納しています。
- GoのランタイムがGCを実行する際に、この
funcdata
を参照して、どのメモリ領域がポインタであり、GCの対象となるかを判断します。
-
ELF (Executable and Linkable Format):
- Unix系オペレーティングシステム (Linux、BSDなど) で広く使用されている、実行可能ファイル、オブジェクトコード、共有ライブラリの標準ファイルフォーマットです。
- プログラムのコード、データ、シンボルテーブル、再配置情報などが、セクションと呼ばれる論理的なブロックに分割されて格納されます。
- リンカーは、これらのセクションを適切に配置し、シンボルを解決して、実行可能なELFファイルを生成します。
-
debug['v']
:- Goリンカーの内部で使用されるデバッグフラグの一つで、リンカーの冗長レベルを制御します。
debug['v']
がtrue
(または1
) の場合、基本的な冗長メッセージが出力されます。debug['v'] > 1
の場合、さらに詳細なデバッグメッセージが出力されます。
技術的詳細
このコミットは、src/cmd/ld/lib.c
ファイルに対して行われた変更を元に戻すものです。具体的には、以下の3つの主要な変更が元に戻されています。
-
冗長出力レベルの調整の巻き戻し:
- 元のコミットでは、
addlib
、autolib
、ldobj
といったリンカーの処理に関するメッセージの出力条件がdebug['v']
からdebug['v'] > 1
に変更されていました。これは、これらのメッセージをより詳細なデバッグレベルでのみ表示するようにするためのものでした。 - このコミットでは、これらの条件が再び
debug['v']
に戻されています。これにより、これらのメッセージは-v
フラグを1つだけ指定した場合でも表示されるようになります。
- 元のコミットでは、
-
symsize
出力のフォーマット変更の巻き戻し:- 元のコミットでは、
symsize
の出力にcputime()
が追加されていました。 - このコミットでは、
cputime()
の表示が削除され、symsize = %ud
というシンプルなフォーマットに戻されています。
- 元のコミットでは、
-
pclntab
およびfuncdata
サイズ計算と出力の削除:- これが最も重要な変更点であり、ELFビルドの破壊の原因となった部分と考えられます。
- 元のコミットでは、
pclntab
関数内でfuncdata_bytes
という変数が導入され、各関数のfuncdata
の合計サイズを計算していました。 - また、
pclntab
の処理の最後に、pclntab
のサイズとfuncdata_bytes
の合計サイズを冗長出力 (debug['v']
がtrue
の場合) するコードが追加されていました。 - このコミットでは、
funcdata_bytes
変数の宣言と初期化、funcdata_bytes
の計算ロジック、そしてその出力ロジックがすべて削除されています。
特に、funcdata_bytes
の計算部分では、p->to.sym->hide = 1;
という行が含まれていました。これは、funcdata
に関連するシンボルを「隠す」ことを意図していた可能性があります。このようなシンボルの可視性やリンカーによる処理の変更が、ELFフォーマットのリンキング規則と衝突し、結果としてELFビルドが失敗する原因となった可能性が非常に高いです。ELFリンカーは、シンボルの解決と配置に関して厳格なルールを持っており、Goリンカーがこれらのルールに違反するような方法でシンボルを操作した場合、ビルドエラーが発生します。
コアとなるコードの変更箇所
src/cmd/ld/lib.c
ファイルにおける変更は以下の通りです。
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -231,7 +231,7 @@ addlib(char *src, char *obj)
*p = '\0';
- if(debug['v'] > 1)
+ if(debug['v'])
Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
addlibpath(src, obj, pname, name);
@@ -330,7 +330,7 @@ loadlib(void)
}
for(i=0; i<libraryp; i++) {
- if(debug['v'] > 1)
+ if(debug['v'])
Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref);
iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0;
objfile(library[i].file, library[i].pkg);
@@ -433,7 +433,7 @@ objfile(char *file, char *pkg)
pkg = smprint("%i", pkg);
- if(debug['v'] > 1)
+ if(debug['v'])
Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg);
Bflush(&bso);
f = Bopen(file, 0);
@@ -2049,7 +2049,7 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
}
}
if(debug['v'] || debug['n'])
- Bprint(&bso, "%5.2f symsize = %ud\n", cputime(), symsize);
+ Bprint(&bso, "symsize = %ud\n", symsize);
Bflush(&bso);
}
@@ -2356,9 +2356,7 @@ pclntab(void)
uint32 *havepc, *havefunc;
Sym *ftab, *s;
int32 npcdata, nfuncdata, off, end;
- int64 funcdata_bytes;
- funcdata_bytes = 0;
ftab = lookup("pclntab", 0);
ftab->type = SPCLNTAB;
ftab->reachable = 1;
@@ -2480,13 +2478,8 @@ pclntab(void)
i = p->from.offset;
if(p->to.type == D_CONST)
setuintxx(ftab, off+PtrSize*i, p->to.offset, PtrSize);
- else {
- if(!p->to.sym->hide) {
- funcdata_bytes += p->to.sym->size;
- p->to.sym->hide = 1;
- }
+ else
setaddrplus(ftab, off+PtrSize*i, p->to.sym, p->to.offset);
- }
}
}
off += nfuncdata*PtrSize;
@@ -2513,7 +2506,4 @@ pclntab(void)
setuint32(ftab, start + s->value*4, ftabaddstring(ftab, s->name));
ftab->size = ftab->np;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
}
コアとなるコードの解説
上記の差分は、元のコミットによって導入された変更を正確に元に戻しています。
-
addlib
,autolib
,ldobj
の冗長出力:if(debug['v'] > 1)
がif(debug['v'])
に戻されています。これは、リンカーの冗長メッセージが、より低い冗長レベル (-v
のみ) で表示されるようにするための変更です。元のコミットはこれらのメッセージを-v -v
でのみ表示するように変更していましたが、このコミットでその変更が取り消されました。
-
genasmsym
内のsymsize
出力:Bprint(&bso, "%5.2f symsize = %ud\n", cputime(), symsize);
がBprint(&bso, "symsize = %ud\n", symsize);
に戻されています。これにより、symsize
の出力からCPU時間が削除されます。
-
pclntab
関数内の変更:int64 funcdata_bytes;
の宣言とfuncdata_bytes = 0;
の初期化が削除されています。else { ... }
ブロック全体が削除され、setaddrplus
の呼び出しが直接else
の後に続くように変更されています。この削除されたブロックには、funcdata_bytes
の加算とp->to.sym->hide = 1;
の設定が含まれていました。このhide
フラグの設定が、ELFビルドに問題を引き起こした可能性が高いです。シンボルを「隠す」という操作が、ELFのリンキングプロセスにおいて予期せぬ副作用をもたらしたと考えられます。if(debug['v']) Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
の行が削除されています。これにより、pclntab
とfuncdata
の合計サイズをリンカーの冗長出力に表示する機能が削除されます。
これらの変更は、元のコミットが導入したELFビルドの破壊的なバグを修正するために、その変更を完全に巻き戻すことを目的としています。特に、funcdata_bytes
の計算と関連するシンボルの hide
フラグの設定が、ELFリンカーの動作に悪影響を与えた可能性が非常に高いです。
関連リンク
- 元のコミット (CL 12193043): https://golang.org/cl/12193043 (このコミットによって元に戻された変更)
- このコミット (CL 12202043): https://golang.org/cl/12202043 (この解説の対象となるコミット)
参考にした情報源リンク
- Go言語のソースコード (特に
src/cmd/ld/lib.c
): Go言語の公式リポジトリ - ELF (Executable and Linkable Format) の仕様に関する一般的な情報: Wikipediaや関連する技術文書
- Goの
pclntab
とfuncdata
に関する情報: Goのランタイムに関するブログ記事やドキュメント (例: Goのプロファイリング、デバッグに関する公式ドキュメント) - Goのリンカーに関する情報: Goのツールチェインに関する公式ドキュメントやブログ記事
- Goのコミット履歴とCL (Change List) のシステム: Goの貢献ガイドラインやGerritのインターフェース
- GoのIssue Tracker: 関連するバグ報告や議論 (もしあれば)
[インデックス 16961] ファイルの概要
このコミットは、Go言語のリンカー (cmd/ld
) における以前の変更 (CL 12193043 / cc5858966b08) を元に戻すものです。元の変更は、リンカーの冗長出力 (6l -v
) に pclntab
と funcdata
のサイズ情報を追加し、一部の冗長なメッセージをより詳細なデバッグレベル (-v -v
) に移動させることを目的としていました。しかし、この変更が「すべてのELFビルドを破壊する」という重大な問題を引き起こしたため、このコミットで元に戻されました。
コミット
commit b08d0c2c62c901b69637cb6f13af490c6feacbe6
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Wed Jul 31 15:31:43 2013 -0700
undo CL 12193043 / cc5858966b08
Breaks all ELF builds.
««« original CL description
cmd/ld: report pclntab, funcdata sizes in 6l -v output
Also move chatty recent additions to -v -v.
For what it's worth:
$ go build -o /dev/null -ldflags -v cmd/godoc
...
0.73 pclntab=1259976 bytes, funcdata total 79788 bytes
...
$
R=ken2
CC=cshapiro, golang-dev
https://golang.org/cl/12193043
»»»
R=rsc
CC=golang-dev
https://golang.org/cl/12202043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b08d0c2c62c901b69637cb6f13af490c6feacbe6
元コミット内容
このコミットは、以下の内容を持つ元のコミット (CL 12193043 / cc5858966b08) を元に戻すものです。
- 目的:
cmd/ld
(Goリンカー) の-v
(verbose) 出力にpclntab
とfuncdata
のサイズ情報を追加する。 - 詳細:
go build -ldflags -v
コマンドの出力に、pclntab
とfuncdata
の合計サイズが表示されるようになる。- リンカーのログ出力のうち、最近追加された「おしゃべりな」メッセージを、より詳細なデバッグレベル (
-v -v
またはdebug['v'] > 1
) に移動させる。
- 例:
go build -o /dev/null -ldflags -v cmd/godoc
の実行例が示されており、pclntab
とfuncdata total
のサイズが出力されることが示されている。
変更の背景
元のコミット (CL 12193043) は、Goリンカーの冗長出力に有用なデバッグ情報を追加することを意図していました。特に、pclntab
と funcdata
のサイズは、Goバイナリのサイズ分析や、ランタイムの内部構造を理解する上で役立つ情報です。しかし、この変更が実装された結果、「すべてのELFビルドを破壊する」という深刻なリグレッションが発生しました。ELF (Executable and Linkable Format) は、LinuxなどのUnix系システムで広く使用されている実行可能ファイル、オブジェクトコード、共有ライブラリの標準フォーマットです。このリグレッションは、GoプログラムがELF形式でビルドできなくなることを意味し、Goの利用可能性に大きな影響を与えるため、迅速に元に戻す必要がありました。
具体的な破壊の原因はコミットメッセージには明記されていませんが、pclntab
や funcdata
の処理方法の変更がELFフォーマットの仕様と衝突したか、リンカーがELFファイルを正しく生成できなくなった可能性が高いです。特に、funcdata_bytes
の計算と関連するシンボルの処理が、ELFのセクション配置やシンボル解決に影響を与えたことが考えられます。Goリンカーは、コンパイルされたGoパッケージと依存関係を単一の実行可能ファイルに結合する役割を担っており、この過程で pclntab
や funcdata
を生成し埋め込みます。これらの内部構造や「マジック値」はGoのバージョン間で進化する可能性があり、それがツールやリンカーの動作に影響を与えることがあります。
前提知識の解説
このコミットを理解するためには、以下のGo言語の内部構造とツールチェインに関する知識が必要です。
-
Goリンカー (
cmd/ld
):- Goのビルドプロセスにおいて、コンパイルされたオブジェクトファイルを結合し、実行可能なバイナリを生成するツールです。
-v
フラグは、リンカーの動作に関する詳細な情報を出力するために使用されます。-v -v
(またはdebug['v'] > 1
) は、さらに詳細なデバッグ情報を表示します。
-
pclntab
(Program Counter Line Table):- Goのバイナリに含まれる重要なデータ構造の一つで、「プログラムカウンタ-行番号テーブル」の略です。
- 主に、スタックトレースの生成、プロファイリング、デバッグなどのランタイム機能で使用されます。
- 特定のプログラムカウンタ (PC) アドレスが、ソースコードのどのファイル、どの行に対応するかをマッピングする情報を含んでいます。
- Goの実行時エラーが発生した際に、人間が読める形式のスタックトレースを出力できるのは、この
pclntab
のおかげです。
-
funcdata
(Function Data):- Goのバイナリに含まれる、関数に関する追加のメタデータです。
- ガベージコレクション (GC) のために、各関数がスタック上に持つポインタの位置情報などを格納しています。
- GoのランタイムがGCを実行する際に、この
funcdata
を参照して、どのメモリ領域がポインタであり、GCの対象となるかを判断します。
-
ELF (Executable and Linkable Format):
- Unix系オペレーティングシステム (Linux、BSDなど) で広く使用されている、実行可能ファイル、オブジェクトコード、共有ライブラリの標準ファイルフォーマットです。
- プログラムのコード、データ、シンボルテーブル、再配置情報などが、セクションと呼ばれる論理的なブロックに分割されて格納されます。
- リンカーは、これらのセクションを適切に配置し、シンボルを解決して、実行可能なELFファイルを生成します。
-
debug['v']
:- Goリンカーの内部で使用されるデバッグフラグの一つで、リンカーの冗長レベルを制御します。
debug['v']
がtrue
(または1
) の場合、基本的な冗長メッセージが出力されます。debug['v'] > 1
の場合、さらに詳細なデバッグメッセージが出力されます。
技術的詳細
このコミットは、src/cmd/ld/lib.c
ファイルに対して行われた変更を元に戻すものです。具体的には、以下の3つの主要な変更が元に戻されています。
-
冗長出力レベルの調整の巻き戻し:
- 元のコミットでは、
addlib
、autolib
、ldobj
といったリンカーの処理に関するメッセージの出力条件がdebug['v']
からdebug['v'] > 1
に変更されていました。これは、これらのメッセージをより詳細なデバッグレベルでのみ表示するようにするためのものでした。 - このコミットでは、これらの条件が再び
debug['v']
に戻されています。これにより、これらのメッセージは-v
フラグを1つだけ指定した場合でも表示されるようになります。
- 元のコミットでは、
-
symsize
出力のフォーマット変更の巻き戻し:- 元のコミットでは、
symsize
の出力にcputime()
が追加されていました。 - このコミットでは、
cputime()
の表示が削除され、symsize = %ud
というシンプルなフォーマットに戻されています。
- 元のコミットでは、
-
pclntab
およびfuncdata
サイズ計算と出力の削除:- これが最も重要な変更点であり、ELFビルドの破壊の原因となった部分と考えられます。
- 元のコミットでは、
pclntab
関数内でfuncdata_bytes
という変数が導入され、各関数のfuncdata
の合計サイズを計算していました。 - また、
pclntab
の処理の最後に、pclntab
のサイズとfuncdata_bytes
の合計サイズを冗長出力 (debug['v']
がtrue
の場合) するコードが追加されていました。 - このコミットでは、
funcdata_bytes
変数の宣言と初期化、funcdata_bytes
の計算ロジック、そしてその出力ロジックがすべて削除されています。
特に、funcdata_bytes
の計算部分では、p->to.sym->hide = 1;
という行が含まれていました。これは、funcdata
に関連するシンボルを「隠す」ことを意図していた可能性があります。このようなシンボルの可視性やリンカーによる処理の変更が、ELFフォーマットのリンキング規則と衝突し、結果としてELFビルドが失敗する原因となった可能性が非常に高いです。ELFリンカーは、シンボルの解決と配置に関して厳格なルールを持っており、Goリンカーがこれらのルールに違反するような方法でシンボルを操作した場合、ビルドエラーが発生します。Goリンカーが破損したELFバイナリを生成したり、セクションがゼロアウトされたりする問題は過去にも報告されており、環境固有の問題や再現が難しいケースもあります。
コアとなるコードの変更箇所
src/cmd/ld/lib.c
ファイルにおける変更は以下の通りです。
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -231,7 +231,7 @@ addlib(char *src, char *obj)
*p = '\0';
- if(debug['v'] > 1)
+ if(debug['v'])
Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
addlibpath(src, obj, pname, name);
@@ -330,7 +330,7 @@ loadlib(void)
}
for(i=0; i<libraryp; i++) {
- if(debug['v'] > 1)
+ if(debug['v'])
Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref);
iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0;
objfile(library[i].file, library[i].pkg);
@@ -433,7 +433,7 @@ objfile(char *file, char *pkg)
pkg = smprint("%i", pkg);
- if(debug['v'] > 1)
+ if(debug['v'])
Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg);
Bflush(&bso);
f = Bopen(file, 0);
@@ -2049,7 +2049,7 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
}
}
if(debug['v'] || debug['n'])
- Bprint(&bso, "%5.2f symsize = %ud\n", cputime(), symsize);
+ Bprint(&bso, "symsize = %ud\n", symsize);
Bflush(&bso);
}
@@ -2356,9 +2356,7 @@ pclntab(void)
uint32 *havepc, *havefunc;
Sym *ftab, *s;
int32 npcdata, nfuncdata, off, end;
- int64 funcdata_bytes;
- funcdata_bytes = 0;
ftab = lookup("pclntab", 0);
ftab->type = SPCLNTAB;
ftab->reachable = 1;
@@ -2480,13 +2478,8 @@ pclntab(void)
i = p->from.offset;
if(p->to.type == D_CONST)
setuintxx(ftab, off+PtrSize*i, p->to.offset, PtrSize);
- else {
- if(!p->to.sym->hide) {
- funcdata_bytes += p->to.sym->size;
- p->to.sym->hide = 1;
- }
+ else
setaddrplus(ftab, off+PtrSize*i, p->to.sym, p->to.offset);
- }
}
}
off += nfuncdata*PtrSize;
@@ -2513,7 +2506,4 @@ pclntab(void)
setuint32(ftab, start + s->value*4, ftabaddstring(ftab, s->name));
ftab->size = ftab->np;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
}
コアとなるコードの解説
上記の差分は、元のコミットによって導入された変更を正確に元に戻しています。
-
addlib
,autolib
,ldobj
の冗長出力:if(debug['v'] > 1)
がif(debug['v'])
に戻されています。これは、リンカーの冗長メッセージが、より低い冗長レベル (-v
のみ) で表示されるようにするための変更です。元のコミットはこれらのメッセージを-v -v
でのみ表示するように変更していましたが、このコミットでその変更が取り消されました。
-
genasmsym
内のsymsize
出力:Bprint(&bso, "%5.2f symsize = %ud\n", cputime(), symsize);
がBprint(&bso, "symsize = %ud\n", symsize);
に戻されています。これにより、symsize
の出力からCPU時間が削除されます。
-
pclntab
関数内の変更:int64 funcdata_bytes;
の宣言とfuncdata_bytes = 0;
の初期化が削除されています。else { ... }
ブロック全体が削除され、setaddrplus
の呼び出しが直接else
の後に続くように変更されています。この削除されたブロックには、funcdata_bytes
の加算とp->to.sym->hide = 1;
の設定が含まれていました。このhide
フラグの設定が、ELFビルドに問題を引き起こした可能性が高いです。シンボルを「隠す」という操作が、ELFのリンキングプロセスにおいて予期せぬ副作用をもたらしたと考えられます。ELFのシンボル解決は厳格であり、シンボルの可視性や属性の変更は、リンカーが期待する動作と異なる結果を生むことがあります。if(debug['v']) Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
の行が削除されています。これにより、pclntab
とfuncdata
の合計サイズをリンカーの冗長出力に表示する機能が削除されます。
これらの変更は、元のコミットが導入したELFビルドの破壊的なバグを修正するために、その変更を完全に巻き戻すことを目的としています。特に、funcdata_bytes
の計算と関連するシンボルの hide
フラグの設定が、ELFリンカーの動作に悪影響を与えた可能性が非常に高いです。
関連リンク
- 元のコミット (CL 12193043): https://golang.org/cl/12193043 (このコミットによって元に戻された変更)
- このコミット (CL 12202043): https://golang.org/cl/12202043 (この解説の対象となるコミット)
参考にした情報源リンク
- Go言語のソースコード (特に
src/cmd/ld/lib.c
): Go言語の公式リポジトリ - ELF (Executable and Linkable Format) の仕様に関する一般的な情報: Wikipediaや関連する技術文書
- Goの
pclntab
とfuncdata
に関する情報: Goのランタイムに関するブログ記事やドキュメント (例: Goのプロファイリング、デバッグに関する公式ドキュメント) - Goのリンカーに関する情報: Goのツールチェインに関する公式ドキュメントやブログ記事
- Goのコミット履歴とCL (Change List) のシステム: Goの貢献ガイドラインやGerritのインターフェース
- GoのIssue Tracker: 関連するバグ報告や議論 (もしあれば)
- Web検索: "Go linker pclntab funcdata ELF build issues"