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

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

このコミットは、Goコンパイラ、ブートストラッププロセス、およびGOOS(Go Operating System)のサポートリストにdragonfly/amd64アーキテクチャのサポートを追加することを目的としています。これにより、Go言語がDragonFly BSDオペレーティングシステム上でAMD64アーキテクチャをターゲットとして動作するバイナリを生成できるようになります。

コミット

commit 71dc91db0ff711c39fbf86ca9425c65442e40b57
Author: Joel Sing <jsing@google.com>
Date:   Sat Aug 24 01:18:04 2013 +1000

    all: compiler/bootstrap for dragonfly/amd64
    
    Add dragonfly/amd64 support to the Go compiler, bootstrap and GOOS list.
    
    R=devon.odell, bradfitz
    CC=golang-dev
    https://golang.org/cl/12796050

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

https://github.com/golang/go/commit/71dc91db0ff711c39fbf86ca9425c65442e40b57

元コミット内容

all: compiler/bootstrap for dragonfly/amd64

Add dragonfly/amd64 support to the Go compiler, bootstrap and GOOS list.

R=devon.odell, bradfitz
CC=golang-dev
https://golang.org/cl/12796050

変更の背景

Go言語は、その設計思想の一つとして、多様なプラットフォームへの対応を重視しています。GOOS(Go Operating System)とGOARCH(Go Architecture)の組み合わせによって、Goプログラムは様々なオペレーティングシステムとCPUアーキテクチャ上で動作するバイナリを生成できます。

このコミットが行われた背景には、Go言語が当時まだ正式にサポートしていなかったDragonFly BSDオペレーティングシステムとAMD64アーキテクチャの組み合わせ(dragonfly/amd64)への対応を拡充するという目的があります。Goコンパイラ自体がGoで書かれているため、新しいプラットフォームをサポートするには、そのプラットフォーム上でGoコンパイラをビルドできる「ブートストラップ」プロセスが必要になります。この変更は、Goエコシステムがより多くの環境で利用可能になるための重要な一歩でした。

前提知識の解説

GOOSとGOARCH

Go言語のビルドシステムでは、環境変数のGOOSGOARCHを使用して、ターゲットとするオペレーティングシステムとCPUアーキテクチャを指定します。例えば、GOOS=linux GOARCH=amd64と設定すると、Linux上で動作するAMD64アーキテクチャ向けのバイナリが生成されます。このコミットは、GOOSの有効な値にdragonflyを追加し、GOARCHamd64との組み合わせをサポートします。

クロスコンパイル

Go言語は強力なクロスコンパイル機能を内蔵しています。これは、あるオペレーティングシステム(例: macOS)上で、別のオペレーティングシステム(例: Linux)向けのバイナリを生成できる能力です。このコミットは、GoコンパイラがDragonFly BSD向けのバイナリをクロスコンパイルできるようにするための基盤を構築します。

ブートストラッププロセス

GoコンパイラはGo言語で書かれています。新しいプラットフォームでGoコンパイラをビルドするには、そのプラットフォームで動作する既存のGoコンパイラが必要です。この循環的な依存関係を解決するために、「ブートストラップ」というプロセスが用いられます。通常、これは以前のバージョンのGoコンパイラ(またはC言語で書かれたツールチェーン)を使用して、新しいプラットフォーム向けのGoコンパイラを最初にビルドすることを指します。このコミットは、dragonfly/amd64向けのブートストラップを可能にするための変更を含んでいます。

ELFバイナリとダイナミックリンカ

ELF (Executable and Linkable Format) は、Unix系システムで広く使われている実行可能ファイル、オブジェクトコード、共有ライブラリの標準フォーマットです。DragonFly BSDもELFを使用しています。ELFバイナリは、プログラムが実行時に必要とする共有ライブラリをロードするために、ダイナミックリンカ(またはダイナミックローダ)のパスを内部に持っています。このコミットでは、DragonFly BSDのダイナミックリンカのパス(/libexec/ld-elf.so.2)がGoのリンカに認識されるように変更が加えられています。

ビルドタグ (+build)

Goのソースコードでは、ファイルの先頭に+buildディレクティブを記述することで、特定のGOOSGOARCHの組み合わせでのみそのファイルをコンパイル対象とするように指定できます。このコミットでは、dragonflyをサポート対象に含めるために、既存のビルドタグが更新されています。

技術的詳細

このコミットは、Goツールチェーンの複数のコンポーネントにわたる変更を含んでいます。

  1. リンカ (src/cmd/6l, src/cmd/ld) の変更:

    • src/cmd/6l/asm.c: DragonFly BSD向けのダイナミックリンカのパスとして/libexec/ld-elf.so.2が追加されました。また、Hdragonfly(DragonFlyのヘッダタイプ)が64ビットアドレスを扱うように設定され、ELF形式でのシンボルオフセット計算やアセンブル処理に組み込まれました。
    • src/cmd/6l/obj.c: リンカのヘッダタイプとしてHdragonflyが追加され、コマンドラインオプション-H dragonflyがDragonFly ELF実行ファイルを生成することを示すコメントが追加されました。また、Hdragonflyが他のELFベースのOS(Linux, FreeBSD, NetBSD, OpenBSD)と同様に、TLS(Thread Local Storage)オフセットの処理でFSレジスタを使用するように設定されました。
    • src/cmd/6l/pass.c: HdragonflyHEADTYPEのチェックに追加され、TLS関連のパッチ処理(D_INDIR+D_GSからD_INDIR+D_FSへの変換)が適用されるようになりました。
    • src/cmd/ld/doc.go: リンカのドキュメントに-H dragonflyオプションの説明が追加されました。
    • src/cmd/ld/elf.c: ELFバイナリ生成時に、Hdragonflyの場合にダイナミックリンカのパスとしてdragonflydynldが使用されるように設定されました。また、ELFヘッダのEI_OSABIフィールドがHdragonflyの場合にELFOSABI_NONEに設定されるようになりました。
    • src/cmd/ld/elf.hsrc/cmd/ld/lib.h: dragonflydynldの宣言と、Hdragonflyヘッダタイプの定義が追加されました。
  2. ビルドシステム (src/cmd/dist) の変更:

    • src/cmd/dist/build.c: Goがサポートするオペレーティングシステムのリストokgoos"dragonfly"が追加されました。
    • src/cmd/dist/unix.c: __DragonFly__マクロが定義されている場合に、gohostos"dragonfly"に設定されるように変更されました。これは、distツールがホストOSを正しく識別するために必要です。
  3. Goコマンド (src/cmd/go) の変更:

    • src/cmd/go/signal_unix.go: Unix系OS向けのシグナル処理ファイルにおいて、ビルドタグにdragonflyが追加されました。これにより、DragonFly BSD上でもこのシグナル処理が有効になります。
  4. 標準ライブラリ (src/lib9, src/pkg/go/build) の変更:

    • src/lib9/run_unix.csrc/lib9/tempdir_unix.c: Unix系OS向けのランタイムサポートファイルにおいて、ビルドタグにdragonflyが追加されました。
    • src/libmach/dragonfly.c: DragonFly BSD向けのデバッグ情報やプロセス制御に関するスタブファイルが新規追加されました。現時点では未実装の機能が多いことを示すコメントが含まれていますが、将来的な拡張のためのプレースホルダーとなります。
    • src/pkg/go/build/deps_test.go: テストで使用されるgeese(Go OSのリスト)変数に"dragonfly"が追加されました。
    • src/pkg/go/build/syslist.go: GoがサポートするOSのリストを定義するgoosList定数に"dragonfly"が追加されました。これは、go/buildパッケージがGoのビルド環境を認識するために使用されます。

これらの変更により、Goツールチェーン全体がdragonfly/amd64を認識し、そのプラットフォーム向けのバイナリを生成できるようになります。

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

このコミットで変更された主要なファイルと、その変更の概要は以下の通りです。

  • src/cmd/6l/asm.c: DragonFlyのダイナミックリンカパスとELF処理の追加。
  • src/cmd/6l/obj.c: DragonFlyのヘッダタイプ定義とTLS処理の追加。
  • src/cmd/6l/pass.c: DragonFlyのTLS関連パッチ処理への組み込み。
  • src/cmd/dist/build.c: サポートOSリストにDragonFlyを追加。
  • src/cmd/dist/unix.c: ホストOS識別ロジックにDragonFlyを追加。
  • src/cmd/go/signal_unix.go: ビルドタグにDragonFlyを追加。
  • src/cmd/ld/doc.go: リンカのドキュメントにDragonFlyサポートを追記。
  • src/cmd/ld/elf.c: ELF生成時のDragonFly向けリンカパスとOSABI設定。
  • src/cmd/ld/elf.h: DragonFlyのダイナミックリンカパス宣言。
  • src/cmd/ld/lib.h: DragonFlyのヘッダタイプ定義。
  • src/lib9/run_unix.c: ビルドタグにDragonFlyを追加。
  • src/lib9/tempdir_unix.c: ビルドタグにDragonFlyを追加。
  • src/libmach/dragonfly.c: DragonFly向けのスタブファイル新規作成。
  • src/pkg/go/build/deps_test.go: テスト用OSリストにDragonFlyを追加。
  • src/pkg/go/build/syslist.go: サポートOSリスト定数にDragonFlyを追加。

合計15ファイルが変更され、98行が追加、16行が削除されています。

コアとなるコードの解説

src/cmd/6l/asm.c

char dragonflydynld[] = "/libexec/ld-elf.so.2";
// ...
case Hdragonfly:
    debug['8'] = 1; /* 64-bit addresses */
    break;
// ...
case Hdragonfly:
    symo = rnd(HEADR+segtext.len, INITRND)+rnd(segrodata.len, INITRND)+segdata.filelen;
    symo = rnd(symo, INITRND);
    break;
// ...
case Hdragonfly:
    asmbelf(symo);
    break;

この部分では、DragonFly BSDのダイナミックリンカのパスが定義され、リンカがDragonFly向けのバイナリを生成する際に、64ビットアドレスを扱うこと、シンボルオフセットの計算、そしてELF形式でのアセンブル処理を行うように設定されています。

src/cmd/6l/obj.c

Header headers[] = {
    // ...
    "dragonfly", Hdragonfly,
    // ...
};
// ...
*   -Hdragonfly -Tx -Rx     is DragonFly elf-exec
// ...
case Hdragonfly:    /* dragonfly */
    // ... ELF uses TLS offset negative from FS.
    // ...

リンカが認識するヘッダタイプにHdragonflyが追加され、コマンドラインオプション-H dragonflyがDragonFly ELF実行ファイルを生成することを示すコメントが追加されました。また、DragonFlyが他のELFベースのOSと同様に、TLSオフセットの処理でFSレジスタを使用することが明示されています。

src/cmd/dist/build.c

static char *okgoos[] = {
    "darwin",
    "dragonfly",
    "linux",
    // ...
};

Goのビルドシステムが認識するサポート対象のオペレーティングシステムリストに"dragonfly"が追加されています。これにより、GOOS=dragonflyが有効な値として扱われるようになります。

src/cmd/go/signal_unix.go

// +build darwin dragonfly freebsd linux netbsd openbsd

Goのビルドタグにdragonflyが追加されました。これは、このファイルがDragonFly BSDを含む指定されたOSでのみコンパイルされることを意味します。

src/libmach/dragonfly.c

// This is stubbed out for the moment. Will revisit when the time comes.
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>

int
ctlproc(int pid, char *msg)
{
    USED(pid);
    USED(msg);

    sysfatal("ctlproc unimplemented in DragonFly");
    return -1;
}
// ... (他のスタブ関数)

このファイルは、DragonFly BSD向けのデバッグやプロセス制御に関する機能のプレースホルダーとして新規作成されました。現時点ではほとんどの関数が「未実装」としてsysfatalを呼び出すスタブとなっていますが、将来的な機能拡張のための基盤となります。

src/pkg/go/build/syslist.go

const goosList = "darwin dragonfly freebsd linux netbsd openbsd plan9 windows "

go/buildパッケージがGoのビルド環境を認識するために使用する、サポート対象のOSリストを定義する定数に"dragonfly"が追加されました。

これらの変更は、GoツールチェーンがDragonFly BSD上で動作するバイナリを生成するために必要な、低レベルのリンカ設定から高レベルのビルドシステム、そして標準ライブラリのビルドタグに至るまで、広範囲にわたる調整を示しています。

関連リンク

参考にした情報源リンク