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

[インデックス 17923] ファイルの概要

このコミットは、Goコンパイラのcmd/5g (ARM), cmd/6g (AMD64), cmd/8g (386) において、リンカの共通ライブラリであるliblinkを使用するように変更するものです。これは、Go 1.3におけるリンカの再設計(golang.org/s/go13linker)に向けた準備作業の一環です。

コミット

commit f606c1be805e939e1aebcb9d3e15adf4eb5f7016
Author: Russ Cox <rsc@golang.org>
Date:   Sun Dec 8 22:51:55 2013 -0500

    cmd/5g, cmd/6g, cmd/8g: use liblink
    
    Preparation for golang.org/s/go13linker work.
    
    This CL does not build by itself. It depends on 35740044
    and 35790044 and will be submitted at the same time.
    
    R=iant
    CC=golang-dev
    https://golang.org/cl/34590045

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016

元コミット内容

cmd/5g, cmd/6g, cmd/8g: use liblink

Preparation for golang.org/s/go13linker work.

This CL does not build by itself. It depends on 35740044
and 35790044 and will be submitted at the same time.

変更の背景

このコミットの主な背景は、Go 1.3リリースに向けて計画されていたリンカの大規模な再設計です。Goの初期バージョンでは、各アーキテクチャ(ARM, AMD64, 386など)のコンパイラ(5g, 6g, 8g)がそれぞれ独自のオブジェクトファイル生成ロジックと、それに密接に関連するリンカとの連携部分を持っていました。これにより、新しいアーキテクチャのサポートやリンカの機能改善を行う際に、各コンパイラの実装を個別に変更する必要があり、開発のオーバーヘッドが大きくなっていました。

golang.org/s/go13linkerで言及されているように、Go 1.3ではリンカのコードベースを共通化し、よりモジュール化された設計に移行する目標がありました。この目標を達成するためには、コンパイラ側がリンカとやり取りする方法も標準化する必要がありました。

このコミットは、その標準化の一歩として、各コンパイラが共通のリンカライブラリであるliblinkを利用するように変更することで、将来のリンカの変更がコンパイラに与える影響を最小限に抑え、コードの重複を排除することを目的としています。コミットメッセージにある「This CL does not build by itself. It depends on 35740044 and 35790044 and will be submitted at the same time.」という記述は、この変更がリンカ側の変更と密接に連携しており、単独では機能しないことを示しています。

前提知識の解説

Goコンパイラの構造 (Go 1.x以前)

Goのコンパイラは、gc (Go Compiler) と呼ばれるフロントエンドと、各アーキテクチャ固有のバックエンド(例: 5g for ARM, 6g for AMD64, 8g for 386)に分かれていました。

  • gc: Go言語のソースコードを解析し、抽象構文木 (AST) を生成し、型チェック、最適化、中間コード(PcodeまたはSSAの前段階)への変換を行います。
  • 5g, 6g, 8gなど: gcから出力された中間コードを受け取り、各アーキテクチャの機械語に変換し、オブジェクトファイルを生成します。このオブジェクトファイルは、最終的にリンカによって実行可能ファイルに結合されます。

リンカの役割

リンカは、コンパイラが生成した複数のオブジェクトファイルやライブラリを結合し、実行可能なプログラムを生成するツールです。シンボル解決(関数や変数のアドレスを決定する)や、再配置(コード内のアドレス参照を実際のメモリ位置に調整する)などの重要なタスクを実行します。

liblinkは、Goのリンカが内部的に使用する共通のライブラリです。Go 1.3以前は、各コンパイラがオブジェクトファイルを生成する際に、リンカと密接に連携する独自のコードを持っていました。liblinkを導入することで、これらの共通のリンカ関連の処理を一つのライブラリに集約し、コンパイラとリンカ間のインターフェースを標準化することが可能になります。これにより、リンカの内部実装が変更されても、コンパイラ側の変更を最小限に抑えることができます。

golang.org/s/go13linker

これは、Go 1.3におけるリンカの再設計に関する設計ドキュメントまたは提案を指します。Goのリンカは元々Plan 9のツールチェインから派生しており、その設計はシンプルでしたが、大規模なプロジェクトやクロスコンパイルの複雑さが増すにつれて、いくつかの課題を抱えていました。go13linkerの取り組みは、これらの課題を解決し、リンカのパフォーマンス、機能、保守性を向上させることを目的としていました。このコミットは、その大規模な変更の前提となる、コンパイラ側の準備作業です。

技術的詳細

このコミットは、主に以下の技術的な変更を含んでいます。

  1. AddrおよびProg構造体の削除:

    • src/cmd/5g/gg.h, src/cmd/6g/gg.h, src/cmd/8g/gg.hから、Addr (アドレス表現) および Prog (命令表現) 構造体の定義が削除されています。これらの構造体は、各コンパイラが独自に持っていたオブジェクトコード生成のための内部表現でした。
    • liblinkの導入により、これらの共通のデータ構造はliblink内で定義され、コンパイラはliblinkが提供するインターフェースを通じてオブジェクトコードを生成するようになります。これにより、各コンパイラがこれらの構造体を個別に管理する必要がなくなります。
  2. zname, zfile, zhist, zaddr, zsymreset, zsym, zsymaddr, dumpfuncs関数の削除:

    • src/cmd/*/gobj.cから、オブジェクトファイルの書き出しやシンボル管理に関連する多数の関数が削除されています。これらの関数は、各コンパイラがオブジェクトファイルを生成する際の低レベルな処理を担っていました。
    • これらの機能はliblinkに集約され、コンパイラはliblinkが提供する高レベルなAPIを呼び出すことで、同様の処理を実行するようになります。これにより、各コンパイラの実装が大幅に簡素化されます。
  3. linksym関数の導入と利用:

    • 多くの箇所で、シンボル(Sym*)を直接使用していた部分がlinksym(sym)という形式に変更されています。linksymは、liblinkが提供する関数で、コンパイラ内部のシンボルをリンカが認識できる形式に変換する役割を担います。これは、コンパイラとリンカ間のシンボル管理の橋渡しをする重要な変更です。
    • 例えば、p->to.sym = n->left->sym;p->to.sym = linksym(n->left->sym); に変更されています。
  4. LinkArch構造体の利用:

    • src/cmd/*/galign.cにおいて、LinkArch* thelinkarch = &linkarm; のような行が追加されています。これは、各アーキテクチャ固有のリンカ設定をliblinkに渡すための構造体です。これにより、liblinkは各アーキテクチャの特性(アライメント、レジスタなど)を考慮したオブジェクトコードを生成できるようになります。
  5. newplist関数の変更:

    • src/cmd/*/gsubr.cnewplist関数(プログラムリストの管理に関連)が、linknewplist(ctxt)を呼び出すように変更されています。これは、プログラムリストの管理もliblinkに委譲されることを示しています。

これらの変更は、各コンパイラがオブジェクトファイルを生成する際の低レベルな詳細をliblinkに抽象化し、コンパイラコードの複雑性を軽減するとともに、リンカの共通化を促進するためのものです。

コアとなるコードの変更箇所

このコミットは、Goコンパイラの複数のアーキテクチャ固有のバックエンド(cmd/5g, cmd/6g, cmd/8g)と、共通のフロントエンド(cmd/gc)にわたる広範な変更を含んでいます。

特に影響が大きいのは以下のファイル群です。

  • src/cmd/*/gg.h: 各アーキテクチャのヘッダーファイル。AddrProg構造体の定義が削除されています。
    • src/cmd/5g/gg.h
    • src/cmd/6g/gg.h
    • src/cmd/8g/gg.h
  • src/cmd/*/gobj.c: 各アーキテクチャのオブジェクトファイル生成ロジック。zname, zfile, zhist, zaddr, zsymreset, zsym, zsymaddr, dumpfuncsなど、オブジェクトファイルの書き出しとシンボル管理に関連する多数の関数が削除されています。
    • src/cmd/5g/gobj.c
    • src/cmd/6g/gobj.c
    • src/cmd/8g/gobj.c
  • src/cmd/*/ggen.c, src/cmd/*/gsubr.c, src/cmd/*/list.c, src/cmd/*/peep.c, src/cmd/*/reg.c: これらのファイルでは、Addr構造体やSym構造体の直接的な操作が、linksym関数を介した操作や、nilチェックへの変更など、liblinkのインターフェースに合わせた変更が行われています。
  • src/cmd/*/galign.c: LinkArch* thelinkarch変数の追加。
    • src/cmd/5g/galign.c
    • src/cmd/6g/galign.c
    • src/cmd/8g/galign.c
  • src/cmd/gc/obj.c: gcフロントエンドにおけるオブジェクト関連の処理も変更されています。

変更の性質上、削除行が挿入行を大幅に上回っており、これは多くのコードが各コンパイラからliblinkへと移動したことを示しています。

コアとなるコードの解説

このコミットの核心は、Goコンパイラのバックエンドが、オブジェクトファイルの生成とシンボル管理の責任を、共通のliblinkライブラリに委譲する点にあります。

具体的な変更のパターンは以下の通りです。

  1. データ構造の抽象化:

    • 以前は各コンパイラが独自に定義していたAddrProgといった低レベルなデータ構造が、ヘッダーファイルから削除されました。これは、これらの構造体がliblink内部で管理されるようになり、コンパイラはそれらを直接操作する必要がなくなったことを意味します。
    • 例: src/cmd/5g/gg.hからAddrProgの定義が削除。
  2. オブジェクトファイル書き出しロジックの共通化:

    • zname, zfile, zhist, zaddr, dumpfuncsといった、オブジェクトファイルへのバイト列書き込みやシンボル情報のシリアライズを担当していた関数群が、gobj.cファイルから削除されました。
    • これらの機能はliblinkに移行し、コンパイラはliblinkが提供するより抽象化されたAPI(例: linknewplist, linksym)を呼び出すことで、同様の処理を実行します。これにより、各アーキテクチャのgobj.cファイルは大幅に簡素化されます。
    • 例: src/cmd/5g/gobj.cからzname関数が削除。
  3. シンボル解決の委譲:

    • コンパイラ内部で管理されていたシンボル(Sym*)が、リンカが理解できる形式に変換されるようになりました。これは、linksym関数を介して行われます。
    • 例: p->to.sym = n->left->sym;p->to.sym = linksym(n->left->sym); に変更。これは、n->left->symというコンパイラ内部のシンボル表現を、リンカが処理できるシンボル表現に変換してp->to.symに設定していることを示します。
  4. アーキテクチャ固有情報のリンカへの引き渡し:

    • 各アーキテクチャのgalign.cファイルにLinkArch* thelinkarch変数が追加され、アーキテクチャ固有のリンカ設定(例: linkarm, linkamd64, link386)がliblinkに渡されるようになりました。これにより、liblinkは各アーキテクチャの特性に応じたコード生成や最適化を行うことができます。
    • 例: src/cmd/5g/galign.cLinkArch* thelinkarch = &linkarm;が追加。

これらの変更は、Goコンパイラのバックエンドとリンカの間の結合度を緩め、リンカの再設計を容易にするための重要なステップです。これにより、将来的にリンカの内部実装が大きく変更されても、コンパイラ側のコードを大幅に修正する必要がなくなります。

関連リンク

参考にした情報源リンク

  • コミットハッシュ: f606c1be805e939e1aebcb9d3e15adf4eb5f7016
  • GitHubコミットページ: https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016
  • Go issue tracker (関連するissueやCLがある可能性): https://go.dev/issue
  • Goのメーリングリストアーカイブ (golang-devなど、議論の履歴がある可能性): https://groups.google.com/g/golang-dev
  • golang.org/s/go13linker (このコミットの背景にある設計ドキュメント): このリンクはGoの内部ドキュメントへのショートリンクであり、直接アクセスはできませんが、Goのソースコードリポジトリや関連する設計ドキュメントでその内容が公開されている可能性があります。
  • liblinkに関するGoのソースコード: src/cmd/linkディレクトリ以下にliblinkの実装が含まれています。```markdown

[インデックス 17923] ファイルの概要

このコミットは、Goコンパイラのcmd/5g (ARM), cmd/6g (AMD64), cmd/8g (386) において、リンカの共通ライブラリであるliblinkを使用するように変更するものです。これは、Go 1.3におけるリンカの再設計(golang.org/s/go13linker)に向けた準備作業の一環です。

コミット

commit f606c1be805e939e1aebcb9d3e15adf4eb5f7016
Author: Russ Cox <rsc@golang.org>
Date:   Sun Dec 8 22:51:55 2013 -0500

    cmd/5g, cmd/6g, cmd/8g: use liblink
    
    Preparation for golang.org/s/go13linker work.
    
    This CL does not build by itself. It depends on 35740044
    and 35790044 and will be submitted at the same time.
    
    R=iant
    CC=golang-dev
    https://golang.org/cl/34590045

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016

元コミット内容

cmd/5g, cmd/6g, cmd/8g: use liblink

Preparation for golang.org/s/go13linker work.

This CL does not build by itself. It depends on 35740044
and 35790044 and will be submitted at the same time.

変更の背景

このコミットの主な背景は、Go 1.3リリースに向けて計画されていたリンカの大規模な再設計です。Goの初期バージョンでは、各アーキテクチャ(ARM, AMD64, 386など)のコンパイラ(5g, 6g, 8g)がそれぞれ独自のオブジェクトファイル生成ロジックと、それに密接に関連するリンカとの連携部分を持っていました。これにより、新しいアーキテクチャのサポートやリンカの機能改善を行う際に、各コンパイラの実装を個別に変更する必要があり、開発のオーバーヘッドが大きくなっていました。

golang.org/s/go13linkerで言及されているように、Go 1.3ではリンカのコードベースを共通化し、よりモジュール化された設計に移行する目標がありました。この目標を達成するためには、コンパイラ側がリンカとやり取りする方法も標準化する必要がありました。

このコミットは、その標準化の一歩として、各コンパイラが共通のリンカライブラリであるliblinkを利用するように変更することで、将来のリンカの変更がコンパイラに与える影響を最小限に抑え、コードの重複を排除することを目的としています。コミットメッセージにある「This CL does not build by itself. It depends on 35740044 and 35790044 and will be submitted at the same time.」という記述は、この変更がリンカ側の変更と密接に連携しており、単独では機能しないことを示しています。

前提知識の解説

Goコンパイラの構造 (Go 1.x以前)

Goのコンパイラは、gc (Go Compiler) と呼ばれるフロントエンドと、各アーキテクチャ固有のバックエンド(例: 5g for ARM, 6g for AMD64, 8g for 386)に分かれていました。

  • gc: Go言語のソースコードを解析し、抽象構文木 (AST) を生成し、型チェック、最適化、中間コード(PcodeまたはSSAの前段階)への変換を行います。
  • 5g, 6g, 8gなど: gcから出力された中間コードを受け取り、各アーキテクチャの機械語に変換し、オブジェクトファイルを生成します。このオブジェクトファイルは、最終的にリンカによって実行可能ファイルに結合されます。

リンカの役割

リンカは、コンパイラが生成した複数のオブジェクトファイルやライブラリを結合し、実行可能なプログラムを生成するツールです。シンボル解決(関数や変数のアドレスを決定する)や、再配置(コード内のアドレス参照を実際のメモリ位置に調整する)などの重要なタスクを実行します。

liblinkは、Goのリンカが内部的に使用する共通のライブラリです。Go 1.3以前は、各コンパイラがオブジェクトファイルを生成する際に、リンカと密接に連携する独自のコードを持っていました。liblinkを導入することで、これらの共通のリンカ関連の処理を一つのライブラリに集約し、コンパイラとリンカ間のインターフェースを標準化することが可能になります。これにより、リンカの内部実装が変更されても、コンパイラ側の変更を最小限に抑えることができます。

golang.org/s/go13linker

これは、Go 1.3におけるリンカの再設計に関する設計ドキュメントまたは提案を指します。Goのリンカは元々Plan 9のツールチェインから派生しており、その設計はシンプルでしたが、大規模なプロジェクトやクロスコンパイルの複雑さが増すにつれて、いくつかの課題を抱えていました。go13linkerの取り組みは、これらの課題を解決し、リンカのパフォーマンス、機能、保守性を向上させることを目的としていました。このコミットは、その大規模な変更の前提となる、コンパイラ側の準備作業です。

技術的詳細

このコミットは、主に以下の技術的な変更を含んでいます。

  1. AddrおよびProg構造体の削除:

    • src/cmd/5g/gg.h, src/cmd/6g/gg.h, src/cmd/8g/gg.hから、Addr (アドレス表現) および Prog (命令表現) 構造体の定義が削除されています。これらの構造体は、各コンパイラが独自に持っていたオブジェクトコード生成のための内部表現でした。
    • liblinkの導入により、これらの共通のデータ構造はliblink内で定義され、コンパイラはliblinkが提供するインターフェースを通じてオブジェクトコードを生成するようになります。これにより、各コンパイラがこれらの構造体を個別に管理する必要がなくなります。
  2. zname, zfile, zhist, zaddr, zsymreset, zsym, zsymaddr, dumpfuncs関数の削除:

    • src/cmd/*/gobj.cから、オブジェクトファイルの書き出しやシンボル管理に関連する多数の関数が削除されています。これらの関数は、各コンパイラがオブジェクトファイルを生成する際の低レベルな処理を担っていました。
    • これらの機能はliblinkに集約され、コンパイラはliblinkが提供する高レベルなAPIを呼び出すことで、同様の処理を実行するようになります。これにより、各コンパイラの実装が大幅に簡素化されます。
  3. linksym関数の導入と利用:

    • 多くの箇所で、シンボル(Sym*)を直接使用していた部分がlinksym(sym)という形式に変更されています。linksymは、liblinkが提供する関数で、コンパイラ内部のシンボルをリンカが認識できる形式に変換する役割を担います。これは、コンパイラとリンカ間のシンボル管理の橋渡しをする重要な変更です。
    • 例えば、p->to.sym = n->left->sym;p->to.sym = linksym(n->left->sym); に変更されています。
  4. LinkArch構造体の利用:

    • src/cmd/*/galign.cにおいて、LinkArch* thelinkarch = &linkarm; のような行が追加されています。これは、各アーキテクチャ固有のリンカ設定をliblinkに渡すための構造体です。これにより、liblinkは各アーキテクチャの特性(アライメント、レジスタなど)を考慮したオブジェクトコードを生成できるようになります。
  5. newplist関数の変更:

    • src/cmd/*/gsubr.cnewplist関数(プログラムリストの管理に関連)が、linknewplist(ctxt)を呼び出すように変更されています。これは、プログラムリストの管理もliblinkに委譲されることを示しています。

これらの変更は、各コンパイラがオブジェクトファイルを生成する際の低レベルな詳細をliblinkに抽象化し、コンパイラコードの複雑性を軽減するとともに、リンカの共通化を促進するためのものです。

コアとなるコードの変更箇所

このコミットは、Goコンパイラの複数のアーキテクチャ固有のバックエンド(cmd/5g, cmd/6g, cmd/8g)と、共通のフロントエンド(cmd/gc)にわたる広範な変更を含んでいます。

特に影響が大きいのは以下のファイル群です。

  • src/cmd/*/gg.h: 各アーキテクチャのヘッダーファイル。AddrProg構造体の定義が削除されています。
    • src/cmd/5g/gg.h
    • src/cmd/6g/gg.h
    • src/cmd/8g/gg.h
  • src/cmd/*/gobj.c: 各アーキテクチャのオブジェクトファイル生成ロジック。zname, zfile, zhist, zaddr, zsymreset, zsym, zsymaddr, dumpfuncsなど、オブジェクトファイルの書き出しとシンボル管理に関連する多数の関数が削除されています。
    • src/cmd/5g/gobj.c
    • src/cmd/6g/gobj.c
    • src/cmd/8g/gobj.c
  • src/cmd/*/ggen.c, src/cmd/*/gsubr.c, src/cmd/*/list.c, src/cmd/*/peep.c, src/cmd/*/reg.c: これらのファイルでは、Addr構造体やSym構造体の直接的な操作が、linksym関数を介した操作や、nilチェックへの変更など、liblinkのインターフェースに合わせた変更が行われています。
  • src/cmd/*/galign.c: LinkArch* thelinkarch変数の追加。
    • src/cmd/5g/galign.c
    • src/cmd/6g/galign.c
    • src/cmd/8g/galign.c
  • src/cmd/gc/obj.c: gcフロントエンドにおけるオブジェクト関連の処理も変更されています。

変更の性質上、削除行が挿入行を大幅に上回っており、これは多くのコードが各コンパイラからliblinkへと移動したことを示しています。

コアとなるコードの解説

このコミットの核心は、Goコンパイラのバックエンドが、オブジェクトファイルの生成とシンボル管理の責任を、共通のliblinkライブラリに委譲する点にあります。

具体的な変更のパターンは以下の通りです。

  1. データ構造の抽象化:

    • 以前は各コンパイラが独自に定義していたAddrProgといった低レベルなデータ構造が、ヘッダーファイルから削除されました。これは、これらの構造体がliblink内部で管理されるようになり、コンパイラはそれらを直接操作する必要がなくなったことを意味します。
    • 例: src/cmd/5g/gg.hからAddrProgの定義が削除。
  2. オブジェクトファイル書き出しロジックの共通化:

    • zname, zfile, zhist, zaddr, dumpfuncsといった、オブジェクトファイルへのバイト列書き込みやシンボル情報のシリアライズを担当していた関数群が、gobj.cファイルから削除されました。
    • これらの機能はliblinkに移行し、コンパイラはliblinkが提供するより抽象化されたAPI(例: linknewplist, linksym)を呼び出すことで、同様の処理を実行します。これにより、各アーキテクチャのgobj.cファイルは大幅に簡素化されます。
    • 例: src/cmd/5g/gobj.cからzname関数が削除。
  3. シンボル解決の委譲:

    • コンパイラ内部で管理されていたシンボル(Sym*)が、リンカが理解できる形式に変換されるようになりました。これは、linksym関数を介して行われます。
    • 例: p->to.sym = n->left->sym;p->to.sym = linksym(n->left->sym); に変更。これは、n->left->symというコンパイラ内部のシンボル表現を、リンカが処理できるシンボル表現に変換してp->to.symに設定していることを示します。
  4. アーキテクチャ固有情報のリンカへの引き渡し:

    • 各アーキテクチャのgalign.cファイルにLinkArch* thelinkarch変数が追加され、アーキテクチャ固有のリンカ設定(例: linkarm, linkamd64, link386)がliblinkに渡されるようになりました。これにより、liblinkは各アーキテクチャの特性に応じたコード生成や最適化を行うことができます。
    • 例: src/cmd/5g/galign.cLinkArch* thelinkarch = &linkarm;が追加。

これらの変更は、Goコンパイラのバックエンドとリンカの間の結合度を緩め、リンカの再設計を容易にするための重要なステップです。これにより、将来的にリンカの内部実装が大きく変更されても、コンパイラ側のコードを大幅に修正する必要がなくなります。

関連リンク

参考にした情報源リンク

  • コミットハッシュ: f606c1be805e939e1aebcb9d3e15adf4eb5f7016
  • GitHubコミットページ: https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016
  • Go issue tracker (関連するissueやCLがある可能性): https://go.dev/issue
  • Goのメーリングリストアーカイブ (golang-devなど、議論の履歴がある可能性): https://groups.google.com/g/golang-dev
  • golang.org/s/go13linker (このコミットの背景にある設計ドキュメント): このリンクはGoの内部ドキュメントへのショートリンクであり、直接アクセスはできませんが、Goのソースコードリポジトリや関連する設計ドキュメントでその内容が公開されている可能性があります。
  • liblinkに関するGoのソースコード: src/cmd/linkディレクトリ以下にliblinkの実装が含まれています。