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

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

コミット

commit a8e55f8858da7e79ba3aafbde61a7326b411b3fe
Author: Lucio De Re <lucio.dere@gmail.com>
Date:   Sat Mar 9 14:54:56 2013 -0800

    cmd/8l/obj.c: NetBSD passes the test, Hnetbsd added.
    
    myrtle$ go version
    go version devel +d533352b414d Sat Mar 09 05:39:15 2013 +0100 netbsd/386
    myrtle$ time go test -ldflags -hostobj ../misc/cgo/test
    ok      _/var/project/GoLang/misc/cgo/test      10.962s
       68.63s real    49.60s user    19.06s system
    myrtle$ uname -a
    NetBSD myrtle.plan9.local 6.0_BETA2 NetBSD 6.0_BETA2 (GENERIC) i386
    
    R=rsc
    CC=golang-dev
    https://golang.org/cl/7641047

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

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

元コミット内容

このコミットは、Go言語のリンカである8l(現在はgo tool linkの一部)のobj.cファイルに、NetBSDプラットフォームのサポートを追加するものです。具体的には、cgoを使用する際に、ホストオブジェクト(hostobj)のリンキングがNetBSD環境で正しく機能するように、Hnetbsdというヘッドタイプ(OSタイプ)を許可リストに追加しています。

コミットメッセージには、NetBSD/i386環境でgo test -ldflags -hostobj ../misc/cgo/testコマンドが成功したことが示されており、これによりNetBSD上でのcgoの動作が検証されています。

変更の背景

Go言語はクロスプラットフォーム対応を重視しており、様々なオペレーティングシステムやアーキテクチャで動作するように設計されています。cgoはGoプログラムからC言語のコードを呼び出すための機能であり、外部のCライブラリを利用する際に不可欠です。

このコミットが行われた2013年当時、Go言語のNetBSDサポートは進化の途上にありました。特にcgoのような、GoランタイムとOSネイティブの機能が密接に連携する部分では、各OS固有のリンキングやオブジェクトファイルの扱いに関する調整が必要でした。

cmd/8l/obj.cは、Goリンカがオブジェクトファイルを処理する際のロジックを定義しているファイルです。hostobjは、cgoによって生成された、または外部から提供されたC言語のオブジェクトファイルを指します。これらのオブジェクトファイルは、Goのリンカによって最終的な実行可能ファイルに結合されます。

以前のリンカの実装では、hostobjの利用が特定のOS(例えばLinux)に限定されており、NetBSDのような新しいターゲットOSでは明示的に許可されていませんでした。この制限により、NetBSD上でcgoを使用しようとすると、リンカがhostobjを処理できずにエラーとなる可能性がありました。

このコミットは、NetBSD環境でのcgoのテストが成功したことを受けて、リンカがNetBSDのhostobjを正しく扱えるようにするための修正です。これにより、NetBSDユーザーがGo言語でcgoを利用したアプリケーションを開発・実行できるようになるための重要な一歩となりました。

前提知識の解説

  • Go言語のリンカ (8l / go tool link): Go言語のビルドプロセスにおいて、コンパイルされたGoパッケージやC言語のオブジェクトファイルを結合して実行可能ファイルを生成するツールです。歴史的には8l(386アーキテクチャ向けリンカ)のようなアーキテクチャ固有のリンカが存在しましたが、現在ではgo tool linkとして統合されています。リンカは、Goのランタイム、標準ライブラリ、ユーザーコード、そしてcgoによって生成されたCオブジェクトコードなどを一つにまとめ上げます。

  • cgo: Go言語の標準機能の一つで、GoプログラムからC言語の関数を呼び出したり、C言語のデータ構造を扱ったりするためのメカニズムです。cgoを使用すると、GoのコードとCのコードを混在させることができ、既存のCライブラリをGoプロジェクトで再利用する際に非常に有用です。cgoが有効な場合、GoのビルドシステムはCソースファイルをシステムのCコンパイラ(GCCやClangなど)でコンパイルし、その結果生成されたオブジェクトファイルをGoのリンカに渡します。

  • hostobj (ホストオブジェクト): cgoの文脈において、hostobjはホストシステム(Goプログラムが実行されるターゲットOS/アーキテクチャ)のCコンパイラによって生成されたオブジェクトファイルを指します。これらは通常、cgoがGoとCの間のインターフェースコードを生成し、それをCコンパイラでコンパイルした結果として得られます。Goのリンカは、これらのhostobjをGoのコードとリンクして最終的なバイナリを生成します。

  • ヘッドタイプ (Head Type / HEADTYPE): Goのリンカやコンパイラ内部で、ターゲットとなるオペレーティングシステムとアーキテクチャを識別するために使用される内部的な列挙型または定数です。例えば、HlinuxはLinux、HdarwinはmacOS、そしてこのコミットで追加されたHnetbsdはNetBSDを指します。リンカは、このヘッドタイプに基づいて、特定のOSに固有のリンキング規則やシステムコール、オブジェクトファイルのフォーマットなどを適用します。

  • NetBSD: UNIXライクなオープンソースのオペレーティングシステムの一つです。非常に移植性が高く、多くの異なるハードウェアアーキテクチャで動作することで知られています。Go言語はNetBSDを公式にサポートしており、このコミットはNetBSD上でのGo開発環境、特にcgoを利用した開発の安定性を向上させるものです。

技術的詳細

このコミットの技術的な核心は、Goリンカのsrc/cmd/8l/obj.cファイル内のmain関数におけるswitch文の変更です。このswitch文は、リンカがhostobjを処理する際に、どのオペレーティングシステム(ヘッドタイプ)に対して許可するかを決定しています。

元のコードでは、hostobjの使用が許可されているのはHlinux(Linux)の場合のみでした。それ以外のデフォルトケースでは、sysfatal関数を呼び出して致命的なエラーを発生させ、「cannot use -hostobj with -H %s」というメッセージを出力していました。これは、リンカがhostobjを処理するために必要なOS固有の知識やロジックが、Linux以外のOSでは不足していることを意味していました。

このコミットでは、既存のcase Hlinux:ブロックにcase Hnetbsd:が追加されています。これにより、リンカはHnetbsd(NetBSD)の場合にもhostobjの利用を許可し、エラーを発生させずに処理を続行できるようになります。

この変更は、NetBSD環境でcgoが生成するCオブジェクトファイル(hostobj)をGoのリンカが正しく認識し、Goのコードとリンクできるようにするために不可欠です。NetBSDのシステムコール規約、ABI(Application Binary Interface)、オブジェクトファイルフォーマットなどがGoのリンカによって適切に扱われるようになったことを示唆しています。

コミットメッセージに含まれるテスト実行結果は、この変更が実際にNetBSD/i386環境でcgoを使用したテストを成功させたことを裏付けています。これは、GoのNetBSDサポートが成熟し、cgoのような複雑な機能も安定して動作するようになったことを示しています。

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

変更はsrc/cmd/8l/obj.cファイルの一箇所のみです。

--- a/src/cmd/8l/obj.c
+++ b/src/cmd/8l/obj.c
@@ -147,6 +147,7 @@ main(int argc, char *argv[])
 		default:
 			sysfatal("cannot use -hostobj with -H %s", headstr(HEADTYPE));
 		case Hlinux:
+		case Hnetbsd:
 			break;
 		}
 	}

コアとなるコードの解説

このコードスニペットは、Goリンカのmain関数の一部であり、コマンドライン引数で-hostobjフラグが指定された場合の処理ロジックを示しています。

  • if(debug['H']) { ... }: これは、デバッグフラグHが設定されている場合に、hostobj関連の処理を行うブロックです。-hostobjフラグは、cgoを使用する際に、GoのリンカがC言語のオブジェクトファイルをリンクする必要があることを示します。

  • switch(HEADTYPE) { ... }: HEADTYPEは、Goのビルドターゲットとなるオペレーティングシステムを示す内部的な変数です。このswitch文は、現在のターゲットOSに基づいて異なるリンキング動作を決定します。

  • default:: 以前のコードでは、Hlinux以外のすべてのHEADTYPEに対して、このdefaultケースが実行されていました。sysfatal関数は、致命的なエラーを報告し、プログラムを終了させます。このエラーメッセージ「cannot use -hostobj with -H %s」は、指定されたOS(headstr(HEADTYPE)で表示される)ではhostobjの利用がサポートされていないことをユーザーに伝えます。

  • case Hlinux:: このケースは、ターゲットOSがLinuxの場合に実行されます。break;文があるため、特別な処理は行われず、hostobjの利用が許可されることを意味します。

  • + case Hnetbsd:: このコミットによって追加された行です。これにより、ターゲットOSがNetBSDの場合も、Hlinuxと同様にbreak;が実行され、hostobjの利用が許可されるようになります。つまり、NetBSD環境でもcgoによって生成されたCオブジェクトファイルをGoのリンカが問題なく処理できるようになります。

この変更は、GoのリンカがNetBSDのABIやオブジェクトファイルフォーマットを理解し、cgoとの連携を可能にするための重要な設定変更です。

関連リンク

参考にした情報源リンク