Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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リンカのアーキテクチャを近代化し、将来の機能拡張とパフォーマンス改善のための基盤を築くことにあります。具体的には、以下の課題に対処することを目的としています。

  1. グローバル変数の乱立: 従来のリンカは、多くのグローバル変数に依存しており、コードの理解と保守を困難にしていました。また、リンカの処理を並列化する上での大きな障壁となっていました。
  2. アーキテクチャ固有コードの重複と混在: 各アーキテクチャ(x86, ARM, AMD64など)のリンカ(5l, 6l, 8l)には、共通のロジックが重複して存在していました。また、アーキテクチャ非依存のロジックとアーキテクチャ固有のロジックが混在しており、コードの再利用性と保守性が低い状態でした。
  3. ツール間の構造体の不統一: アセンブラ、コンパイラ、リンカといったGoツールチェーンの異なるコンポーネント間で、ProgAddrといった重要なデータ構造が統一されていませんでした。これにより、ツール間の連携が複雑になり、共通の処理を実装することが困難でした。
  4. 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.csrc/cmd/ld/pcln.cといったファイルは、アーキテクチャ非依存のリンカパスやGoのPCLN(Program Counter Line Number)テーブル生成ロジックを扱うようになります。これにより、コードの重複が排除され、リンカ全体のコードベースがより整理されます。

ProgAddr構造体の統一とinclude/link.hへの移動

Goのコンパイラ、アセンブラ、リンカは、それぞれが独自のProgAddr構造体を持っていました。これは、ツール間で命令やアドレス情報を共有する際に、変換や調整が必要となる原因となっていました。

このコミットでは、ProgAddr構造体をアーキテクチャ非依存の形式に統一し、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構造体: リンカが必要とするシンボル情報(名前、型、バージョン、アドレス、サイズ、再配置リスト、セクション情報など)を保持します。
  • ProgAddr構造体は、シンボルへの参照としてLSym*を使用するようになります。

コンパイラは引き続き独自のSym構造体を使用しますが、オブジェクトファイルを生成する際に、対応するLSym情報をProgAddr構造体内に適切に埋め込む責任を負います。これにより、リンカは一貫して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 (変更):
    • float32float64の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の導入です。

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.hProgAddr 構造体

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)、fromtoはオペランドのアドレスを表します。
  • Addrは、命令のオペランドがメモリ、レジスタ、定数、シンボルなど、どこを指すかを示します。symフィールドは、シンボルへの参照を保持します。

この統一は、リンカがアーキテクチャ非依存のパスを実装する上で不可欠です。例えば、命令リストを走査して最適化を行う際に、特定のアーキテクチャに依存しない共通のロジックを記述できるようになります。

include/link.hLSym 構造体

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.clinklookuplinknew

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リンカの設計に関する公式ドキュメントや提案書は、この変更の背景にある思想を深く理解するのに役立ちます。

参考にした情報源リンク