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

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

このコミットは、Go言語のランタイムにおけるNetBSDおよびWindows向けのビルド問題を修正するものです。具体的には、各OSの起動ルーチンを定義するアセンブリファイル内のエントリポイントシンボル名が誤っていたのを訂正しています。

コミット

runtime: fix netbsd, windows build

TBR=golang-dev
CC=golang-dev
https://golang.org/cl/7539043

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

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

元コミット内容

commit efd3d1ffe9d784b006f03e1961567149952b8f19
Author: Russ Cox <rsc@golang.org>
Date:   Wed Mar 6 16:55:08 2013 -0500

    runtime: fix netbsd, windows build
    
    TBR=golang-dev
    CC=golang-dev
    https://golang.org/cl/7539043
---
 src/pkg/runtime/rt0_netbsd_amd64.s  | 2 +-\
 src/pkg/runtime/rt0_windows_amd64.s | 2 +-\
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pkg/runtime/rt0_netbsd_amd64.s b/src/pkg/runtime/rt0_netbsd_amd64.s
index 245a4c0f9b..9e7b78edc6 100644
--- a/src/pkg/runtime/rt0_netbsd_amd64.s
+++ b/src/pkg/runtime/rt0_netbsd_amd64.s
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-TEXT _rt0_amd64_openbsd(SB),7,$-8
+TEXT _rt0_amd64_netbsd(SB),7,$-8
  LEAQ 8(SP), SI // argv
  MOVQ 0(SP), DI // argc
  MOVQ $main(SB), AX
diff --git a/src/pkg/runtime/rt0_windows_amd64.s b/src/pkg/runtime/rt0_windows_amd64.s
index 4fc61dc687..b48c055705 100644
--- a/src/pkg/runtime/rt0_windows_amd64.s
+++ b/src/pkg/runtime/rt0_windows_amd64.s
@@ -4,7 +4,7 @@

 #include "zasm_GOOS_GOARCH.h"

-TEXT _rt0_amd64_darwin(SB),7,$-8
+TEXT _rt0_amd64_windows(SB),7,$-8
  LEAQ 8(SP), SI // argv
  MOVQ 0(SP), DI // argc
  MOVQ $main(SB), AX

変更の背景

このコミットの背景には、Go言語のクロスプラットフォーム対応におけるビルドシステムの問題がありました。Goのランタイムは、各オペレーティングシステム(OS)およびアーキテクチャ(例: amd64)に特化した起動ルーチン(rt0ファイル)を持っています。これらのファイルはアセンブリ言語で記述されており、プログラムがOSによってロードされた際に最初に実行されるコードを含んでいます。

問題は、NetBSDおよびWindows向けのrt0アセンブリファイル内で、エントリポイントとなるシンボル名が誤って定義されていたことにあります。具体的には、NetBSDのファイルでOpenBSDのシンボル名が、WindowsのファイルでmacOS (Darwin) のシンボル名が使われていました。これにより、これらのOS上でGoプログラムをビルドしようとすると、リンカが正しいエントリポイントを見つけられず、ビルドエラーが発生していました。

このコミットは、これらの誤ったシンボル名をそれぞれのOSに合った正しい名前に修正することで、ビルドプロセスを正常化し、NetBSDおよびWindows上でのGoプログラムのコンパイルを可能にすることを目的としています。

前提知識の解説

このコミットを理解するためには、以下の前提知識が役立ちます。

  • Go言語のランタイム (Runtime): Goプログラムは、OSが提供する機能(システムコールなど)を直接利用するのではなく、Goランタイムを介してそれらの機能にアクセスします。ランタイムは、ガベージコレクション、スケジューラ、メモリ管理、チャネル操作など、Go言語の並行処理モデルを支える多くの低レベルな機能を提供します。
  • rt0ファイル: "runtime 0" の略で、Goプログラムが起動する際に最初に実行されるアセンブリ言語で書かれたコードです。これは、C言語におけるcrt0(C runtime 0)に相当します。rt0の主な役割は、OSから制御を受け取った後、スタックの設定、引数の処理、そしてGoランタイムの初期化関数(最終的にはmain関数)へのジャンプを行うことです。OSやアーキテクチャごとに異なるrt0ファイルが存在します。
  • アセンブリ言語 (.sファイル): コンピュータのプロセッサが直接理解できる機械語に非常に近い低レベルなプログラミング言語です。Goのランタイムの一部や、OSとのインターフェース部分は、パフォーマンスやOS固有の機能へのアクセス、あるいは起動シーケンスの制御のためにアセンブリ言語で記述されています。
  • シンボル (Symbol): プログラム内で変数、関数、ラベルなどを識別するために使われる名前です。アセンブリ言語では、TEXTディレクティブなどを使って関数やコードセクションの開始位置にシンボルを定義します。リンカはこれらのシンボルを使って、異なるコンパイル単位(オブジェクトファイル)間で参照を解決し、最終的な実行可能ファイルを生成します。
  • リンカ (Linker): コンパイラによって生成された複数のオブジェクトファイルやライブラリを結合し、実行可能なプログラムを生成するツールです。リンカは、プログラム内のシンボル参照を解決し、各シンボルがメモリ上のどこに配置されるかを決定します。
  • クロスコンパイル (Cross-compilation): あるプラットフォーム(例: Linux x86-64)で、別のプラットフォーム(例: Windows ARM)向けの実行可能ファイルをビルドすることです。Goは強力なクロスコンパイル機能を持ち、GOOS(ターゲットOS)とGOARCH(ターゲットアーキテクチャ)環境変数を設定することで簡単にクロスコンパイルが可能です。このコミットは、クロスコンパイル環境下での特定のOS向けのビルド問題を解決するものです。

技術的詳細

このコミットの技術的な核心は、Goランタイムの起動アセンブリファイルにおけるシンボル名の不一致を修正することです。

Goのビルドシステムでは、特定のOSとアーキテクチャの組み合わせ(例: GOOS=netbsd, GOARCH=amd64)に対応するアセンブリファイルが選択されます。これらのファイルは、プログラムのエントリポイント、つまりOSがプログラムの実行を開始する場所を定義しています。

  • src/pkg/runtime/rt0_netbsd_amd64.s の変更:

    • 変更前: TEXT _rt0_amd64_openbsd(SB),7,$-8
    • 変更後: TEXT _rt0_amd64_netbsd(SB),7,$-8
    • このファイルはNetBSD (amd64) 向けのアセンブリコードを定義しているにもかかわらず、エントリポイントのシンボル名が誤って _rt0_amd64_openbsd となっていました。これはOpenBSD向けのエントリポイント名です。NetBSD向けの正しいシンボル名は _rt0_amd64_netbsd であるべきです。この修正により、リンカがNetBSD上でGoプログラムをビルドする際に、正しいエントリポイントを見つけられるようになります。
  • src/pkg/runtime/rt0_windows_amd64.s の変更:

    • 変更前: TEXT _rt0_amd64_darwin(SB),7,$-8
    • 変更後: TEXT _rt0_amd64_windows(SB),7,$-8
    • 同様に、Windows (amd64) 向けのアセンブリコードを定義しているこのファイルで、エントリポイントのシンボル名が誤って _rt0_amd64_darwin となっていました。これはmacOS (Darwin) 向けのエントリポイント名です。Windows向けの正しいシンボル名は _rt0_amd64_windows であるべきです。この修正により、Windows上でのGoプログラムのビルドが可能になります。

TEXTディレクティブは、Goのアセンブラ(go tool asm)における関数定義の開始を示します。_rt0_amd64_GOOS(SB) の形式は、GOOS部分がターゲットOSを示す慣例的な命名規則に従っています。SBはStatic Baseレジスタを示し、シンボルがグローバルスコープであることを意味します。,7,$-8 は、関数のフレームサイズや引数のオフセットに関する情報ですが、このコミットの主要な変更点ではありません。

この修正は、Goのビルドシステムが各OS/アーキテクチャの組み合わせに対して、適切なアセンブリファイルとシンボル名を正確にマッピングしていることを保証するために重要です。誤ったシンボル名が使用されていると、リンカは必要なエントリポイントを見つけられず、ビルドが失敗します。

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

変更は以下の2つのアセンブリファイルに集中しています。

  1. src/pkg/runtime/rt0_netbsd_amd64.s:

    --- a/src/pkg/runtime/rt0_netbsd_amd64.s
    +++ b/src/pkg/runtime/rt0_netbsd_amd64.s
    @@ -2,7 +2,7 @@
     // Use of this source code is governed by a BSD-style
     // license that can be found in the LICENSE file.
     
    -TEXT _rt0_amd64_openbsd(SB),7,$-8
    +TEXT _rt0_amd64_netbsd(SB),7,$-8
      LEAQ 8(SP), SI // argv
      MOVQ 0(SP), DI // argc
      MOVQ $main(SB), AX
    

    _rt0_amd64_openbsd というシンボル名が _rt0_amd64_netbsd に変更されました。

  2. src/pkg/runtime/rt0_windows_amd64.s:

    --- a/src/pkg/runtime/rt0_windows_amd64.s
    +++ b/src/pkg/runtime/rt0_windows_amd64.s
    @@ -4,7 +4,7 @@
     
     #include "zasm_GOOS_GOARCH.h"
     
    -TEXT _rt0_amd64_darwin(SB),7,$-8
    +TEXT _rt0_amd64_windows(SB),7,$-8
      LEAQ 8(SP), SI // argv
      MOVQ 0(SP), DI // argc
      MOVQ $main(SB), AX
    

    _rt0_amd64_darwin というシンボル名が _rt0_amd64_windows に変更されました。

コアとなるコードの解説

これらの変更は、Goプログラムの起動シーケンスにおいて極めて重要な部分に影響を与えます。

TEXTディレクティブは、Goのアセンブラにおいて新しいテキストセクション(通常は関数)の開始を宣言するために使用されます。その後に続くシンボル名(例: _rt0_amd64_netbsd)は、そのコードブロックのエントリポイントとして機能します。

  • _rt0_amd64_netbsd(SB): これは、NetBSDオペレーティングシステム上でAMD64アーキテクチャのGoプログラムが起動する際のエントリポイントとなる関数(またはコードブロック)のシンボル名です。OSのローダーは、実行可能ファイルをメモリにロードした後、このシンボルで指定されたアドレスから実行を開始します。
  • _rt0_amd64_windows(SB): 同様に、これはWindowsオペレーティングシステム上でAMD64アーキテクチャのGoプログラムが起動する際のエントリポイントとなるシンボル名です。

以前のバージョンでは、NetBSD向けのファイルでOpenBSDのシンボル名が、Windows向けのファイルでmacOS (Darwin) のシンボル名が誤って記述されていました。これは、おそらくコードのコピー&ペーストや、初期の開発段階での命名規則の不徹底に起因するものと考えられます。

この修正により、各OSのビルドプロセスにおいて、リンカは対応するrt0アセンブリファイル内で正しいエントリポイントシンボルを見つけることができるようになり、結果としてGoプログラムが正しく起動できるようになります。これは、Goのクロスプラットフォーム対応の堅牢性を高めるための、細部ながらも重要な修正です。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード(特にsrc/pkg/runtimeディレクトリ内のアセンブリファイル)
  • Go言語のビルドシステムに関するドキュメント
  • アセンブリ言語の基本とリンカの動作に関する一般的な知識