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

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

このコミットは、Go言語のビルドツールがPlan 9オペレーティングシステム向けのi386およびamd64アーキテクチャのバイナリを認識できるようにするための変更です。具体的には、src/cmd/go/build.goファイル内のobjectMagic変数に、これらのPlan 9バイナリを識別するためのマジックバイトシーケンスが追加されました。これにより、go buildgo installといったコマンドが、Plan 9環境で生成された実行ファイルを正しく処理できるようになります。

コミット

commit 48bd5c501095acc4d9a7cc471906d99c984324f1
Author: Akshat Kumar <seed@mail.nanosouffle.net>
Date:   Mon Oct 1 15:04:52 2012 -0400

    cmd/go/build: Add magic data for Plan 9 binaries.
    
    This change allows the Go build and install tools to
    recognize Plan 9 i386 and amd64 binaries.
    
    R=rsc, r, rminnich
    CC=golang-dev
    https://golang.org/cl/6575064

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

https://github.com/golang/go/commit/48bd5c501095acc4d9a7cc471906d99c984324f1

元コミット内容

cmd/go/build: Add magic data for Plan 9 binaries.

This change allows the Go build and install tools to
recognize Plan 9 i386 and amd64 binaries.

R=rsc, r, rminnich
CC=golang-dev
https://golang.org/cl/6575064

変更の背景

Go言語のビルドシステムは、様々なオペレーティングシステムやアーキテクチャに対応するために、生成されるバイナリの種類を正確に識別する必要があります。これは、クロスコンパイルや、異なる環境でビルドされたバイナリを扱う際に特に重要です。

このコミットが行われた2012年当時、GoはPlan 9オペレーティングシステムもサポートしていました。しかし、Goのビルドツール(cmd/go/buildパッケージ)が、Plan 9環境で生成されたi386およびamd64アーキテクチャの実行ファイルを正しく「オブジェクトファイル」として認識するための情報が不足していました。その結果、これらのバイナリを扱う際に問題が発生する可能性がありました。

この変更の目的は、go buildgo installといったコマンドが、Plan 9のi386およびamd64バイナリを適切に識別し、処理できるようにすることです。これにより、GoのPlan 9サポートがより堅牢になり、開発者はPlan 9環境でGoプログラムをよりスムーズにビルド・実行できるようになります。

前提知識の解説

Plan 9 from Bell Labs

Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルシステムとして表現し、それらをネットワーク越しに透過的にアクセスできるという特徴を持っています。Unixとは異なる独自のバイナリフォーマット(a.outフォーマット)を使用しており、実行ファイルのヘッダ部分に特定のマジックナンバー(識別子)を含んでいます。

マジックナンバー (Magic Number)

コンピュータサイエンスにおいて、マジックナンバーとは、ファイル形式やプロトコルを識別するためにファイルの先頭や特定のオフセットに配置されるバイト列のことです。実行ファイルの場合、オペレーティングシステムやローダーは、このマジックナンバーを読み取ることで、そのファイルがどの種類の実行ファイル(例: ELF, PE, Mach-O, a.outなど)であり、どのアーキテクチャ(例: i386, amd64, ARMなど)向けにコンパイルされたものかを判断します。

Go言語のビルドツールも、同様にobjectMagicという内部的なリストを用いて、既知の実行ファイル形式のマジックナンバーを保持しています。これにより、Goツールは与えられたファイルが実行可能オブジェクトであるかどうか、そしてその種類を判別します。

Plan 9 a.out フォーマットとマジックナンバー

Plan 9の実行ファイルは、独自のa.outフォーマットを使用しています。このフォーマットでは、実行ファイルのヘッダにマジックナンバーが含まれており、これによってCPUアーキテクチャが識別されます。ウェブ検索の結果によると、Plan 9のa.out.hヘッダのExec構造体にはmagicフィールドが定義されており、このマジックナンバーは特定の計算式 (((4*b)+0)*b)+7bはアーキテクチャ固有のベース番号)によって算出されます。

このコミットで追加されたマジックナンバーは、Plan 9のi386およびamd64アーキテクチャに対応するものです。

  • Plan 9 i386: 0x00, 0x00, 0x01, 0xEB
  • Plan 9 amd64: 0x00, 0x00, 0x8a, 0x97

これらのバイト列は、Plan 9の実行ファイルが特定のアーキテクチャ向けにビルドされたものであることを示す識別子として機能します。

技術的詳細

Goのビルドシステムにおいて、src/cmd/go/build.goファイルは、Goのソースコードのビルド、インストール、テストなどを行うためのロジックを含んでいます。このファイルには、様々な種類のオブジェクトファイル(実行ファイルやライブラリなど)を識別するためのobjectMagicというバイトスライスのスライス([][]byte)が定義されています。

objectMagicは、既知の実行ファイル形式の先頭バイト列(マジックナンバー)を格納しており、isObject関数などの内部関数が、与えられたファイルがこれらのマジックナンバーのいずれかに一致するかどうかをチェックすることで、そのファイルが実行可能なオブジェクトであるかを判断します。

このコミットでは、objectMagic変数に以下の2つのマジックバイトシーケンスが追加されました。

  1. {0x00, 0x00, 0x01, 0xEB}: これはPlan 9のi386アーキテクチャ向けバイナリのマジックナンバーです。
  2. {0x00, 0x00, 0x8a, 0x97}: これはPlan 9のamd64アーキテクチャ向けバイナリのマジックナンバーです。

これらのマジックナンバーがobjectMagicに追加されることで、Goのビルドツールは、Plan 9環境でコンパイルされたi386およびamd64バイナリを、他のオペレーティングシステムやアーキテクチャのバイナリと同様に、正しくオブジェクトファイルとして認識できるようになります。これにより、go buildgo installコマンドがこれらのバイナリを適切に処理し、例えば依存関係の解決やインストールパスの決定などを行うことが可能になります。

この変更は、GoツールチェーンがPlan 9環境との互換性を維持し、強化するために不可欠なものでした。

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

--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -946,6 +946,8 @@ var objectMagic = [][]byte{
 	{0xCE, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 32-bit
 	{0xCF, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 64-bit
 	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
+	{0x00, 0x00, 0x01, 0xEB},                         // Plan 9 i386
+	{0x00, 0x00, 0x8a, 0x97},                         // Plan 9 amd64
 }
 
 func isObject(s string) bool {

コアとなるコードの解説

上記のコード差分は、src/cmd/go/build.goファイル内のobjectMagic変数への変更を示しています。

objectMagicは、Goのビルドツールが様々な種類の実行可能ファイルやオブジェクトファイルを識別するために使用する、マジックバイトシーケンスのリストです。各バイトスライスは、特定のファイル形式の先頭バイト列を表しており、コメントでその形式が示されています。

変更前は、Mach-O(macOS/iOS)やPE(Windows)などの一般的なフォーマットのマジックナンバーが含まれていました。

このコミットによって、以下の2行が追加されました。

  • {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
    • この行は、Plan 9オペレーティングシステム上でi386(Intel 32ビット)アーキテクチャ向けにコンパイルされたバイナリを識別するためのマジックナンバーを追加しています。0x00, 0x00, 0x01, 0xEBというバイト列が、Plan 9 i386バイナリのヘッダの先頭に現れることを示しています。
  • {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
    • この行は、Plan 9オペレーティングシステム上でamd64(Intel 64ビット)アーキテクチャ向けにコンパイルされたバイナリを識別するためのマジックナンバーを追加しています。0x00, 0x00, 0x8a, 0x97というバイト列が、Plan 9 amd64バイナリのヘッダの先頭に現れることを示しています。

これらの追加により、isObject関数(この差分には含まれていませんが、objectMagicを利用してファイルの識別を行う関数)が、Plan 9のi386およびamd64バイナリを正しく「オブジェクトファイル」として認識できるようになります。これにより、Goのビルドツールは、これらのバイナリを適切に処理し、ビルド、インストール、リンクなどの操作を正確に実行できるようになります。

関連リンク

参考にした情報源リンク