[インデックス 17920] ファイルの概要
このコミットは、Go言語のリンカの内部構造を大幅に再編成し、将来のリンカの改善(特にGo 1.3リンカの作業)に向けた準備を行うものです。コードの機能的な変更はほとんどなく、主に既存のコードを新しいライブラリ構造に移動し、リンカの状態管理を改善することに焦点を当てています。
コミット
commit 7d507dc6e608e800bc26a5850259bbdb05abdf65
Author: Russ Cox <rsc@golang.org>
Date: Sun Dec 8 22:49:37 2013 -0500
liblink: create new library based on linker code
There is an enormous amount of code moving around in this CL,
but the code is the same, and it is invoked in the same ways.
This CL is preparation for the new linker structure, not the new
structure itself.
The new library's definition is in include/link.h.
The main change is the use of a Link structure to hold all the
linker-relevant state, replacing the smattering of global variables.
The Link structure should both make it clearer which state must
be carried around and make it possible to parallelize more easily
later.
The main body of the linker has moved into the architecture-independent
cmd/ld directory. That includes the list of known header types, so the
distinction between Hplan9x32 and Hplan9x64 is removed (no other
header type distinguished 32- and 64-bit formats), and code for unused
formats such as ipaq kernels has been deleted.
The code being deleted from 5l, 6l, and 8l reappears in liblink or in ld.
Because multiple files are being merged in the liblink directory,
it is not possible to show the diffs nicely in hg.
The Prog and Addr structures have been unified into an
architecture-independent form and moved to link.h, where they will
be shared by all tools: the assemblers, the compilers, and the linkers.
The unification makes it possible to write architecture-independent
traversal of Prog lists, among other benefits.
The Sym structures cannot be unified: they are too fundamentally
different between the linker and the compilers. Instead, liblink defines
an LSym - a linker Sym - to be used in the Prog and Addr structures,
and the linker now refers exclusively to LSyms. The compilers will
keep using their own syms but will fill out the corresponding LSyms in
the Prog and Addr structures.
Although code from 5l, 6l, and 8l is now in a single library, the
code has been arranged so that only one architecture needs to
be linked into a particular program: 5l will not contain the code
needed for x86 instruction layout, for example.
The object file writing code in liblink/obj.c is from cmd/gc/obj.c.
Preparation for golang.org/s/go13linker work.
This CL does not build by itself. It depends on 35740044
and will be submitted at the same time.
R=iant
CC=golang-dev
https://golang.org/cl/35790044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/7d507dc6e608e800bc26a5850259bbdb05abdf65
元コミット内容
このコミットは、Goリンカのコードベースを再編成し、新しいliblink
ライブラリを作成することを目的としています。主な変更点は以下の通りです。
Link
構造体の導入: グローバル変数として散在していたリンカ関連の状態を、Link
構造体に集約します。これにより、状態管理が明確になり、将来的な並列化が容易になります。- アーキテクチャ非依存コードの移動: リンカの主要なロジックが、アーキテクチャ固有の
cmd/5l
,cmd/6l
,cmd/8l
(それぞれARM、AMD64、x86アーキテクチャに対応するリンカ)から、アーキテクチャ非依存のcmd/ld
ディレクトリに移動されます。 Prog
およびAddr
構造体の統一: アセンブラ、コンパイラ、リンカ間で共有されるProg
(プログラム命令)およびAddr
(アドレス)構造体が、アーキテクチャ非依存の形式に統一され、include/link.h
に移動されます。これにより、Prog
リストのアーキテクチャ非依存な走査が可能になります。LSym
の導入:Sym
(シンボル)構造体はリンカとコンパイラで根本的に異なるため統一できませんが、リンカ専用のLSym
(Linker Symbol)が導入され、Prog
およびAddr
構造体内で使用されます。コンパイラは引き続き独自のシンボルを使用しますが、対応するLSym
を埋めるようになります。liblink
ライブラリの作成:5l
,6l
,8l
から削除されたコードは、liblink
またはld
に再配置されます。liblink
は、特定のプログラムにリンクされる際に、そのアーキテクチャに必要なコードのみを含むように構成されます。- オブジェクトファイル書き込みコードの移動:
cmd/gc/obj.c
にあったオブジェクトファイル書き込みコードがliblink/obj.c
に移動されます。 - Go 1.3リンカ作業の準備: この変更は、
golang.org/s/go13linker
で言及されているGo 1.3リンカの作業に向けた準備段階です。
このコミットは、単独ではビルドできない依存関係(コミット35740044)を持つ、大規模なコード移動を伴うものです。
変更の背景
このコミットの主な背景は、Goリンカのアーキテクチャを近代化し、将来の機能拡張とパフォーマンス改善のための基盤を築くことにあります。具体的には、以下の課題に対処することを目的としています。
- グローバル変数の乱立: 従来のリンカは、多くのグローバル変数に依存しており、コードの理解と保守を困難にしていました。また、リンカの処理を並列化する上での大きな障壁となっていました。
- アーキテクチャ固有コードの重複と混在: 各アーキテクチャ(x86, ARM, AMD64など)のリンカ(
5l
,6l
,8l
)には、共通のロジックが重複して存在していました。また、アーキテクチャ非依存のロジックとアーキテクチャ固有のロジックが混在しており、コードの再利用性と保守性が低い状態でした。 - ツール間の構造体の不統一: アセンブラ、コンパイラ、リンカといったGoツールチェーンの異なるコンポーネント間で、
Prog
やAddr
といった重要なデータ構造が統一されていませんでした。これにより、ツール間の連携が複雑になり、共通の処理を実装することが困難でした。 - Go 1.3リンカの目標: Go 1.3では、リンカのパフォーマンスと機能の改善が計画されており、このコミットはそのための前提条件となる大規模なリファクタリングの一環です。特に、リンカの並列化は重要な目標の一つでした。
これらの課題を解決し、よりクリーンでモジュール化された、そして将来的に並列処理が可能なリンカを実現するために、この大規模なコード再編成が行われました。
前提知識の解説
このコミットを理解するためには、以下のGoツールチェーンとリンカに関する基本的な知識が必要です。
Goツールチェーンの構成要素
- コンパイラ (
gc
): Goのソースコードをアセンブリコード(またはオブジェクトファイル)に変換します。 - アセンブラ (
go tool asm
): アセンブリコードをオブジェクトファイルに変換します。 - リンカ (
go tool link
): 複数のオブジェクトファイルとライブラリを結合し、実行可能なバイナリを生成します。
リンカの役割
リンカは、コンパイラやアセンブラによって生成されたオブジェクトファイル(.o
ファイル)を結合し、最終的な実行可能ファイルを生成するプログラムです。その主な役割は以下の通りです。
- シンボル解決: オブジェクトファイル内で参照されている関数や変数のアドレスを解決し、それらが実際に定義されている場所(別のオブジェクトファイルやライブラリ内)にリンクします。
- 再配置: コード内の相対アドレス参照を、最終的な実行可能ファイル内の絶対アドレスに調整します。
- セクションの結合: コード、データ、BSS(初期化されていないデータ)などの異なるセクションを結合し、メモリレイアウトを決定します。
- 実行可能ファイルのフォーマット生成: OSが理解できる形式(ELF, Mach-O, PEなど)で実行可能ファイルを生成します。
Goリンカの歴史的背景と5l
, 6l
, 8l
Go言語の初期のリンカは、Plan 9オペレーティングシステムのツールチェーンに由来しています。Plan 9のリンカは、各アーキテクチャに対して独立したリンカを持っていました。Goもこの設計を踏襲し、以下のようなアーキテクチャ固有のリンカが存在していました。
5l
: ARMアーキテクチャ用リンカ6l
: AMD64アーキテクチャ用リンカ8l
: x86アーキテクチャ用リンカ
これらのリンカは、それぞれが独自のコードベースを持ち、共通のロジックが重複しているという問題がありました。このコミットは、これらのリンカから共通部分を抽出し、再利用可能なライブラリとしてliblink
を構築することを目指しています。
Prog
, Addr
, Sym
構造体
リンカの内部では、プログラムの命令、アドレス、シンボルといった概念を表現するために、以下のようなデータ構造が使用されます。
Prog
(Program Instruction): アセンブリ命令を表す構造体です。命令の種類、オペランド、次の命令へのリンクなどが含まれます。Addr
(Address): 命令のオペランドとして使用されるアドレスを表す構造体です。シンボルへの参照、オフセット、レジスタなどが含まれます。Sym
(Symbol): 関数名、変数名などのシンボルを表す構造体です。シンボルの名前、アドレス、サイズ、型などが含まれます。
これらの構造体は、リンカがオブジェクトファイルを解析し、実行可能ファイルを構築する上で中心的な役割を果たします。
Link
構造体
このコミットで導入されるLink
構造体は、リンカの実行に必要なすべての状態(シンボルテーブル、プログラムリスト、設定など)をカプセル化するためのものです。これにより、リンカのコードがよりモジュール化され、グローバル変数への依存が減少し、将来的にリンカの処理を並列化する際のコンテキスト管理が容易になります。
golang.org/s/go13linker
これは、Go 1.3リリースに向けたリンカの改善作業に関する設計ドキュメントや議論を指すショートリンクです。Go 1.3では、リンカのパフォーマンス向上、特に大規模なプログラムのリンク時間の短縮が重要な目標の一つでした。このコミットは、その目標達成のための基盤となる変更です。
技術的詳細
このコミットは、Goリンカの内部アーキテクチャを根本的に変更するものです。その技術的詳細を以下に説明します。
Link
構造体による状態管理の一元化
従来のGoリンカは、多くのグローバル変数を使用してリンカの状態を管理していました。これは、コードの可読性、保守性、そして特に並列化の可能性を著しく損なっていました。このコミットでは、Link
構造体を導入し、リンカの実行に必要なすべてのコンテキスト情報をこの構造体内に集約します。
Link
構造体には、以下のような情報が含まれます(include/link.h
の定義から抜粋):
thechar
,thestring
: 現在のアーキテクチャを示す文字(例: '5' for ARM, '6' for AMD64)と文字列。headtype
: 実行可能ファイルのヘッダタイプ(ELF, Mach-O, PEなど)。linkmode
: リンクモード(内部リンク、外部リンクなど)。arch
: 現在のアーキテクチャに特化した関数ポインタの集合(LinkArch
構造体)。hash
: シンボルテーブルのハッシュマップ。allsym
: すべてのシンボルのリスト。hist
,ehist
: ファイルと行の履歴情報。plist
,plast
: プログラム命令(Prog
)のリスト。sym_div
,sym_divu
,sym_mod
,sym_modu
: 整数除算・剰余演算のためのランタイムシンボル。curp
,printp
: 現在処理中のProg
ポインタ。libdir
,library
: ライブラリ検索パスとリンクされたライブラリの情報。diag
: エラー診断メッセージ出力関数。
このLink
構造体をリンカの各関数に引数として渡すことで、グローバル変数への依存を排除し、リンカの各部分が明確なコンテキスト内で動作するようにします。これは、将来的にリンカの処理を複数のスレッドやプロセスで並列実行する際に、各スレッドが独立したLink
コンテキストを持つことを可能にするための重要なステップです。
アーキテクチャ非依存コードのcmd/ld
への移動
Goリンカのコードベースは、これまでcmd/5l
, cmd/6l
, cmd/8l
といったアーキテクチャ固有のディレクトリに分散していました。これらのディレクトリには、各アーキテクチャに特化したアセンブリ命令のエンコードや再配置ロジックだけでなく、リンカの共通処理も含まれていました。
このコミットでは、リンカの主要なロジックのうち、アーキテクチャに依存しない部分をcmd/ld
ディレクトリに移動します。これには、シンボル解決、セクションの結合、実行可能ファイルの一般的な構造の生成など、多くの共通処理が含まれます。
例えば、src/cmd/ld/pass.c
やsrc/cmd/ld/pcln.c
といったファイルは、アーキテクチャ非依存のリンカパスやGoのPCLN(Program Counter Line Number)テーブル生成ロジックを扱うようになります。これにより、コードの重複が排除され、リンカ全体のコードベースがより整理されます。
Prog
とAddr
構造体の統一とinclude/link.h
への移動
Goのコンパイラ、アセンブラ、リンカは、それぞれが独自のProg
とAddr
構造体を持っていました。これは、ツール間で命令やアドレス情報を共有する際に、変換や調整が必要となる原因となっていました。
このコミットでは、Prog
とAddr
構造体をアーキテクチャ非依存の形式に統一し、include/link.h
という新しいヘッダファイルに移動します。
Prog
構造体: 命令の種類(as
)、PC値(pc
)、行番号(lineno
)、オペランド(from
,to
)などが含まれます。統一されたことで、異なるアーキテクチャの命令リストを共通のインターフェースで処理できるようになります。Addr
構造体: オペランドのアドレス指定モード(type
)、オフセット(offset
)、レジスタ(reg
)、シンボル(sym
)などが含まれます。
この統一により、Goツールチェーン全体でこれらの基本的なデータ構造を共有できるようになり、コンパイラ、アセンブラ、リンカ間の連携がよりシームレスになります。特に、Prog
リストのアーキテクチャ非依存な走査が可能になることで、リンカの最適化やデバッグツールの開発が容易になります。
LSym
の導入とSym
との分離
Sym
構造体は、コンパイラとリンカでその役割と内容が大きく異なります。コンパイラはソースコードレベルのシンボル情報を扱い、リンカはバイナリレベルのシンボル情報(アドレス、サイズ、再配置情報など)を扱います。この違いから、Sym
構造体を完全に統一することは困難であると判断されました。
そこで、このコミットでは、リンカ専用のシンボル構造体としてLSym
(Linker Symbol)を導入します。
LSym
構造体: リンカが必要とするシンボル情報(名前、型、バージョン、アドレス、サイズ、再配置リスト、セクション情報など)を保持します。Prog
やAddr
構造体は、シンボルへの参照としてLSym*
を使用するようになります。
コンパイラは引き続き独自のSym
構造体を使用しますが、オブジェクトファイルを生成する際に、対応するLSym
情報をProg
やAddr
構造体内に適切に埋め込む責任を負います。これにより、リンカは一貫してLSym
を扱うことができ、コンパイラとリンカ間のインターフェースが明確になります。
liblink
ライブラリの構築
このコミットの最終的な目標の一つは、リンカの共通部分をliblink
という再利用可能なライブラリとして構築することです。src/liblink
ディレクトリが新設され、ここにリンカのコアロジックが配置されます。
liblink
は、各アーキテクチャのリンカ(5l
, 6l
, 8l
)が共有するコードを含みます。しかし、重要なのは、liblink
が「スマート」に設計されている点です。つまり、特定のアーキテクチャのリンカ(例: 5l
)をビルドする際には、そのアーキテクチャに必要なコード(例: ARM命令のレイアウトコード)のみがリンクされ、他のアーキテクチャのコードは含まれません。これにより、リンカのバイナリサイズを最小限に抑えつつ、コードの再利用性を最大化します。
liblink
には、アセンブリ命令のエンコード(asm5.c
, asm6.c
, asm8.c
)、データ操作(data.c
)、オブジェクトファイルの読み込み(rdobj5.c
, rdobj6.c
, rdobj8.c
)、シンボル管理(sym.c
)など、多岐にわたる機能が移動されます。
影響と将来性
このコミットは、Goリンカの内部構造を大幅に改善し、以下の点で将来の発展に貢献します。
- 並列化の促進:
Link
構造体による状態の一元化は、リンカの処理を並列化するための重要な前提条件となります。これにより、マルチコアプロセッサを最大限に活用し、大規模なGoプログラムのリンク時間を大幅に短縮できる可能性があります。 - コードの保守性と拡張性: アーキテクチャ非依存コードの分離、構造体の統一、ライブラリ化により、リンカのコードベースはより理解しやすく、保守しやすくなります。新しいアーキテクチャのサポートや、リンカの新しい最適化を実装する際にも、既存のコードへの影響を最小限に抑えることができます。
- Go 1.3リンカへの道筋: この変更は、Go 1.3で導入される新しいリンカの基盤となります。Go 1.3リンカは、より高速で効率的なリンクを実現することを目標としており、このコミットはそのための重要なステップです。
コアとなるコードの変更箇所
このコミットは大規模なコード移動を伴うため、具体的な変更箇所をファイル単位で詳細に追うのは困難ですが、主要な変更は以下のファイル群に集中しています。
include/link.h
(新規追加):Link
構造体の定義。Addr
構造体、Prog
構造体、LSym
構造体など、リンカが使用する主要なデータ構造の統一された定義。liblink
内の各種関数のプロトタイプ宣言。
include/u.h
(変更):float32
とfloat64
のtypedefが追加されています。これは、リンカが浮動小数点数を扱う際の型定義の明確化のためと考えられます。
src/cmd/5l/
,src/cmd/6l/
,src/cmd/8l/
(大幅な削除と変更):- これらのディレクトリから、アーキテクチャ非依存のリンカロジックが大量に削除され、
liblink
またはcmd/ld
に移動されています。 - 特に、
asm.c
,l.h
,obj.c
,optab.c
,pass.c
,span.c
などのファイルで大幅な削除が見られます。 5.out.h
などのヘッダファイルも、リンカの内部定数定義が変更されています。
- これらのディレクトリから、アーキテクチャ非依存のリンカロジックが大量に削除され、
src/cmd/ld/
(変更):- リンカのアーキテクチャ非依存のコアロジックがこのディレクトリに移動されています。
data.c
,lib.c
,pass.c
,pcln.c
,pobj.c
などのファイルが、新しい共通ロジックを含むように変更または追加されています。
src/liblink/
(新規追加):Makefile
が追加され、liblink
ライブラリのビルド方法が定義されています。asm5.c
,asm6.c
,asm8.c
: 各アーキテクチャのアセンブリ命令エンコードロジック。data.c
: データセクションの操作、シンボルへの値の追加など。go.c
: メモリ割り当てや文字列操作などのユーティリティ関数。ld.c
: リンカの共通ユーティリティ関数(履歴管理、ライブラリ追加など)。obj.c
: オブジェクトファイルの書き込みロジック(cmd/gc/obj.c
から移動)。obj5.c
,obj6.c
,obj8.c
: 各アーキテクチャのオブジェクトファイル書き込み補助。pass.c
: リンカの共通パス処理。pcln.c
: PCLNテーブル生成ロジック。rdobj5.c
,rdobj6.c
,rdobj8.c
: 各アーキテクチャのオブジェクトファイル読み込みロジック。sym.c
: シンボル管理ロジック(LSym
のルックアップ、作成など)。
このコミットは、既存のコードを新しい構造に「移動」することが主であり、機能的な変更は最小限に抑えられています。しかし、その移動の規模は非常に大きく、Goリンカのコードベースの大部分に影響を与えています。
コアとなるコードの解説
このコミットのコアとなる変更は、リンカのデータ構造とコードの組織化にあります。特に重要なのは、Link
構造体、Prog
/Addr
の統一、そしてLSym
の導入です。
include/link.h
の Link
構造体
struct Link
{
int32 thechar; // '5' (arm), '6' (amd64), etc.
char* thestring; // full name of architecture ("arm", "amd64", ..)
int32 goarm; // for arm only, GOARM setting
int headtype;
int linkmode;
LinkArch* arch;
int32 (*ignore)(char*); // do not emit names satisfying this function
int32 debugasm; // -S flag in compiler
// ... (省略) ...
LSym* hash[LINKHASH]; // hash table of all symbols
LSym* allsym;
int32 nsymbol;
// file-line history
Hist* hist;
Hist* ehist;
// all programs
Plist* plist;
Plist* plast;
// code generation
LSym* sym_div;
// ... (省略) ...
Prog* curp;
Prog* printp;
// ... (省略) ...
// for reading input files (during linker)
vlong pc;
char** libdir;
// ... (省略) ...
void (*diag)(char*, ...);
// ... (省略) ...
};
このLink
構造体は、リンカの実行コンテキスト全体をカプセル化します。以前はグローバル変数として散在していたリンカの状態(現在のアーキテクチャ、リンカモード、シンボルテーブル、プログラム命令リスト、デバッグフラグ、エラー診断関数など)がすべてこの構造体のメンバーとして定義されています。
これにより、リンカの各関数はLink* ctxt
という引数を受け取ることで、必要なすべての情報にアクセスできるようになります。これは、コードの依存関係を明確にし、将来的な並列処理(異なるリンカパスやアーキテクチャの処理を並行して実行するなど)を可能にするための基盤となります。
include/link.h
の Prog
と Addr
構造体
struct Addr
{
vlong offset;
union
{
char sval[8];
float64 dval;
Prog* branch; // for 5g, 6g, 8g
} u;
LSym* sym;
LSym* gotype;
short type;
uint8 index;
int8 scale;
int8 reg; // for 5l
int8 name; // for 5l
int8 class; // for 5l
uint8 etype; // for 5g, 6g, 8g
int32 offset2; // for 5l, 8l
struct Node* node; // for 5g, 6g, 8g
int64 width; // for 5g, 6g, 8g
};
struct Prog
{
vlong pc;
int32 lineno;
Prog* link;
short as;
uchar reg; // arm only
uchar scond; // arm only
Addr from;
Addr to;
// for 5g, 6g, 8g internal use
uint32 loc; // TODO: merge with pc?
void* opt;
// for 5l, 6l, 8l internal use
Prog* forwd;
Prog* pcond;
Prog* comefrom; // 6l, 8l
Prog* pcrel; // 5l
int32 spadj;
uchar mark;
uchar back; // 6l, 8l
char ft; /* 6l, 8l oclass cache */
char tt; // 6l, 8l
uchar optab; // 5l
char width; /* fake for DATA */
char mode; /* 16, 32, or 64 */
};
これらの構造体は、Goツールチェーン全体で共有されるように統一されました。以前は各アーキテクチャのリンカやコンパイラが独自の定義を持っていましたが、include/link.h
に一元化されたことで、ツール間のデータ交換が容易になります。
Prog
は、アセンブリ命令の抽象的な表現です。as
フィールドは命令の種類(例:AMOVW
for move word)、from
とto
はオペランドのアドレスを表します。Addr
は、命令のオペランドがメモリ、レジスタ、定数、シンボルなど、どこを指すかを示します。sym
フィールドは、シンボルへの参照を保持します。
この統一は、リンカがアーキテクチャ非依存のパスを実装する上で不可欠です。例えば、命令リストを走査して最適化を行う際に、特定のアーキテクチャに依存しない共通のロジックを記述できるようになります。
include/link.h
の LSym
構造体
struct LSym
{
char* name;
char* extname; // name used in external object files
short type;
short version;
uchar dupok;
uchar reachable;
uchar cgoexport;
uchar special;
uchar stkcheck;
uchar hide;
uchar leaf; // arm only
uchar fnptr; // arm only
int16 symid; // for writing .5/.6/.8 files
int32 dynid;
int32 sig;
int32 plt;
int32 got;
int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
int32 args; // size of stack frame incoming arguments area
int32 locals; // size of stack frame locals area (arm only?)
vlong value;
vlong size;
LSym* hash; // in hash table
LSym* allsym; // in all symbol list
LSym* next; // in text or data list
LSym* sub; // in SSUB list
LSym* outer; // container of sub
LSym* gotype;
LSym* reachparent;
LSym* queue;
char* file;
char* dynimplib;
char* dynimpvers;
struct Section* sect;
Hist2* hist; // for ATEXT
// STEXT
Auto* autom;
Prog* text;
Pcln* pcln;
// SDATA, SBSS
uchar* p;
int32 np;
int32 maxp;
Reloc* r;
int32 nr;
int32 maxr;
};
LSym
は、リンカが内部的に使用するシンボル情報を表現します。コンパイラのSym
とは異なり、LSym
はリンカの視点から見たシンボルの属性(アドレス、サイズ、再配置情報、PLT/GOTエントリ、セクション情報など)に特化しています。
value
: シンボルの最終的なアドレス(またはオフセット)。size
: シンボルのサイズ。type
: シンボルの種類(コード、データ、BSSなど)。r
: シンボルに関連付けられた再配置(Reloc
)のリスト。text
: シンボルがコードの場合、関連するProg
命令のリスト。
この分離により、リンカは自身のドメインに特化したシンボル表現を持つことができ、コンパイラとの間のインターフェースが簡素化されます。
src/liblink/sym.c
の linklookup
と linknew
LSym* linklookup(Link *ctxt, char *name, int v);
Link* linknew(LinkArch*);
LSym* linknewsym(Link *ctxt, char *symb, int v);
src/liblink/sym.c
には、LSym
の検索(linklookup
)や新規作成(linknewsym
)といった基本的なシンボル管理関数が実装されています。これらの関数は、Link
コンテキスト(ctxt
)を引数として受け取ることで、グローバルなシンボルテーブルではなく、特定のリンカインスタンスのシンボルテーブルを操作します。
また、linknew
関数は、新しいLink
コンコンテキストを初期化するために使用されます。これにより、リンカの各実行が独立した状態を持つことが保証されます。
これらの変更は、Goリンカの内部構造をよりモジュール化し、将来の並列化や機能拡張のための強固な基盤を築くものです。
関連リンク
- Go 1.3 Release Notes (Linker improvements): Go 1.3のリリースノートには、このコミットが貢献したリンカの改善に関する情報が含まれている可能性があります。
- Go linker design documents: Goリンカの設計に関する公式ドキュメントや提案書は、この変更の背景にある思想を深く理解するのに役立ちます。
- https://go.dev/s/go13linker (コミットメッセージに記載されているショートリンク)
参考にした情報源リンク
- golang.org/s/go13linker: Go 1.3リンカの作業に関する公式ドキュメント。このコミットの直接的な背景にある設計思想が記述されています。
- Go source code (especially
src/cmd/link
andsrc/cmd/internal/obj
): Goリンカとオブジェクトファイルフォーマットに関する最新かつ最も正確な情報は、Goのソースコード自体にあります。 - Plan 9 from Bell Labs: GoリンカのルーツであるPlan 9のツールチェーンに関する情報も、歴史的背景を理解する上で参考になります。
- ELF, Mach-O, PE file formats: リンカが生成する実行可能ファイルのフォーマットに関する知識は、リンカの動作を深く理解するために不可欠です。