[インデックス 13995] ファイルの概要
このコミットは、Go言語のビルドツールがPlan 9オペレーティングシステム向けのi386およびamd64アーキテクチャのバイナリを認識できるようにするための変更です。具体的には、src/cmd/go/build.go
ファイル内のobjectMagic
変数に、これらのPlan 9バイナリを識別するためのマジックバイトシーケンスが追加されました。これにより、go build
やgo 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 build
やgo 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)+7
(b
はアーキテクチャ固有のベース番号)によって算出されます。
このコミットで追加されたマジックナンバーは、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つのマジックバイトシーケンスが追加されました。
{0x00, 0x00, 0x01, 0xEB}
: これはPlan 9のi386アーキテクチャ向けバイナリのマジックナンバーです。{0x00, 0x00, 0x8a, 0x97}
: これはPlan 9のamd64アーキテクチャ向けバイナリのマジックナンバーです。
これらのマジックナンバーがobjectMagic
に追加されることで、Goのビルドツールは、Plan 9環境でコンパイルされたi386およびamd64バイナリを、他のオペレーティングシステムやアーキテクチャのバイナリと同様に、正しくオブジェクトファイルとして認識できるようになります。これにより、go build
やgo 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バイナリのヘッダの先頭に現れることを示しています。
- この行は、Plan 9オペレーティングシステム上でi386(Intel 32ビット)アーキテクチャ向けにコンパイルされたバイナリを識別するためのマジックナンバーを追加しています。
{0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
- この行は、Plan 9オペレーティングシステム上でamd64(Intel 64ビット)アーキテクチャ向けにコンパイルされたバイナリを識別するためのマジックナンバーを追加しています。
0x00, 0x00, 0x8a, 0x97
というバイト列が、Plan 9 amd64バイナリのヘッダの先頭に現れることを示しています。
- この行は、Plan 9オペレーティングシステム上でamd64(Intel 64ビット)アーキテクチャ向けにコンパイルされたバイナリを識別するためのマジックナンバーを追加しています。
これらの追加により、isObject
関数(この差分には含まれていませんが、objectMagic
を利用してファイルの識別を行う関数)が、Plan 9のi386およびamd64バイナリを正しく「オブジェクトファイル」として認識できるようになります。これにより、Goのビルドツールは、これらのバイナリを適切に処理し、ビルド、インストール、リンクなどの操作を正確に実行できるようになります。
関連リンク
参考にした情報源リンク
- 9p.io (Plan 9
a.out
format): https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQF2HWKK9u0_pBCtgUPZOJkRw42xm2mJvlJGzVesn5Jd5feyTB8zGh7D2DaAAU23G-kHs5YL0xJmetkOA5tDJXDI-R5qmgBWqiUiWQ3lGH7BWvbFWsatz77GqH2-0NpyIA== - googlesource.com (Go
plan9obj
package): https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH4DXAFRoQLCCOc1jrhUTHNPTpwuZP6dPwqzhNpGseipPA4lNlam78i1B4anOPGWdQj5VL8PN3jGHfuNbW4sB1fx7FEDZVHRP11uuEdnDM3NDGXOhm8auIPHCQK_503BQut0Nib_f6nL4t8p_RTnyomStPBA2DE9atAFtWhbzOyCCjfNqG79g==