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

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

このコミットは、Go言語のランタイムがGoogle Native Client (NaCl) 環境をサポートするためのスクリプトとドキュメントを追加するものです。具体的には、nacl/386 および nacl/amd64p32 アーキテクチャ上でのGoプログラムのビルドと実行を可能にするためのヘルパースクリプトと、その設定方法や利用方法を説明するREADMEファイルが追加されています。これにより、Go 1.3におけるNative Clientサポートの基盤が整備されました。

コミット

commit 9cb4963d187e044353e83e7919d2a5302bdd72ac
Author: Dave Cheney <dave@cheney.net>
Date:   Mon Mar 24 12:34:09 2014 +1100

    misc/nacl: add Native Client support scripts and documentation
    
    LGTM=josharian, dan.kortschak
    R=golang-codereviews, josharian, dan.kortschak
    CC=golang-codereviews
    https://golang.org/cl/75080043

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

https://github.com/golang/go/commit/9cb4963d187e044353e83e7919d2a5302bdd72ac

元コミット内容

misc/nacl: add Native Client support scripts and documentation

LGTM=josharian, dan.kortschak
R=golang-codereviews, josharian, dan.kortschak
CC=golang-codereviews
https://golang.org/cl/75080043

変更の背景

この変更は、Go 1.3リリースにおいてGoogle Native Client (NaCl) のサポートを導入する一環として行われました。Native Clientは、ウェブブラウザ内でネイティブコードを安全に実行するためのサンドボックス技術です。Go言語がNaClをサポートすることで、Goプログラムをサンドボックス化された環境で実行できるようになり、特にGo Playgroundのような環境での安全なコード実行や、将来的にはウェブアプリケーションの一部としての利用が期待されました。

このコミットは、GoツールチェインがNaCl環境でビルドおよびテストされたGoバイナリを実行できるようにするための具体的なメカニズムを提供します。Go 1.3では、nacl/386nacl/amd64p32 の2つのNaClアーキテクチャがサポートされました。このコミットで追加されたスクリプトとドキュメントは、開発者がこれらの環境でGoプログラムを開発・実行するための基盤を構築する上で不可欠な要素でした。

なお、GoにおけるNative Clientのサポートは、Go 1.13以降で廃止されています。これは、ウェブ技術の進化や、よりポータブルなWebAssemblyなどの代替技術の台頭によるものです。

前提知識の解説

  • Google Native Client (NaCl): Googleが開発したオープンソース技術で、ウェブブラウザ内でネイティブコード(C/C++など)を安全に実行するためのサンドボックス環境を提供します。これにより、ウェブアプリケーションがCPUに近いパフォーマンスで動作しつつ、セキュリティ上のリスクを低減できます。NaClは、特定のCPUアーキテクチャ(x86-32, x86-64, ARM)に依存するバイナリを対象としていました。
  • サンドボックス (Sandbox): プログラムがシステムのリソース(ファイルシステム、ネットワークなど)にアクセスするのを制限し、悪意のあるコードやバグのあるコードがシステム全体に影響を与えるのを防ぐためのセキュリティメカニズムです。NaClは強力なサンドボックスを提供し、Goプログラムがその中で安全に実行されることを保証します。
  • nacl/386: Native Client環境における32ビットIntelアーキテクチャを指します。
  • nacl/amd64p32: Native Client環境における64ビットIntelアーキテクチャですが、ポインタが32ビットに制限されている特殊なモードを指します。これにより、64ビットのレジスタを利用しつつ、メモリ使用量を抑えることが可能になります。
  • sel_ldr (Secure ELF Loader): Native Client SDKに含まれるツールで、NaClバイナリをロードし、サンドボックス内で実行するためのローダーです。sel_ldr_x86_32 は32ビットNaClバイナリ用、sel_ldr_x86_64 は64ビットNaClバイナリ用です。
  • cmd/go ツール: Go言語のビルド、テスト、実行などを管理するコマンドラインツールです。このコミットでは、cmd/go がNaCl環境での実行を適切に処理できるように拡張されました。
  • クロスコンパイル: あるプラットフォーム(例: Linux x86-64)で、別のプラットフォーム(例: NaCl amd64p32)向けの実行可能ファイルを生成することです。Goは強力なクロスコンパイル機能を備えています。

技術的詳細

このコミットの主要な目的は、GoツールチェインがNative Client環境でGoプログラムをビルドし、実行するためのサポートを統合することです。Goのビルドシステムは、GOOS (オペレーティングシステム) と GOARCH (アーキテクチャ) 環境変数に基づいて動作します。この変更により、GOOS=nacl が設定された場合に、cmd/go ツールが特別な振る舞いをするようになります。

具体的には、cmd/go はNaCl環境向けのバイナリを実行しようとする際、直接実行するのではなく、go_$GOOS_$GOARCH_exec という命名規則に従うヘルパースクリプトを介して実行するようになります。このヘルパースクリプトは、NaClランタイム(sel_ldr)を呼び出し、Goバイナリをサンドボックス内で実行する役割を担います。

追加されたmisc/nacl/READMEは、Native Client SDKのダウンロードとセットアップ、sel_ldrのシンボリックリンク作成、そしてGoのサポートスクリプトのシンボリックリンク作成といった、GoとNaCl環境を連携させるための具体的な手順を詳細に説明しています。これにより、開発者はGOOS=naclGOARCHを設定するだけで、通常のGoのビルドおよびテストコマンド(./make.bash, ./run.bash)を使用してNaCl向けのGoプログラムをコンパイル・実行できるようになります。

go_nacl_386_execgo_nacl_amd64p32_exec スクリプトは、Go環境変数(GOARCH, GOOS, GOROOT)をNaCl環境変数(NACLENV_GOARCH, NACLENV_GOOS, NACLENV_GOROOT, NACLENV_NACLPWD)に変換し、最終的にsel_ldrコマンドを適切な引数で呼び出します。これにより、GoバイナリがNaClサンドボックス内で正しく起動されるようになります。

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

このコミットでは、主に以下の3つのファイルが新規追加されています。

  1. misc/nacl/README: Native Client環境でGoをビルド・実行するための詳細な手順と背景を説明するドキュメント。
  2. misc/nacl/go_nacl_386_exec: nacl/386 アーキテクチャ向けのGoバイナリをNaClサンドボックス内で実行するためのシェルスクリプト。
  3. misc/nacl/go_nacl_amd64p32_exec: nacl/amd64p32 アーキテクチャ向けのGoバイナリをNaClサンドボックス内で実行するためのシェルスクリプト。

これらのファイルはすべて新規追加であり、既存のGoツールチェインのコードに直接的な変更を加えるものではありませんが、cmd/goツールがこれらのスクリプトの存在を認識し、GOOS=naclの場合に利用するように内部的に拡張されたことを示唆しています。

コアとなるコードの解説

追加されたシェルスクリプト go_nacl_386_execgo_nacl_amd64p32_exec は非常にシンプルですが、GoバイナリをNaClサンドボックス内で実行するための重要な役割を担っています。

例として go_nacl_amd64p32_exec の内容を見てみましょう。

#!/bin/bash

eval $(go env)

export NACLENV_GOARCH=$GOARCH
export NACLENV_GOOS=$GOOS
export NACLENV_GOROOT=/go
export NACLENV_NACLPWD=$(pwd | sed "s;$GOROOT;/go;")
 
exec sel_ldr_x86_64 -l /dev/null -S -e "$@"
  1. #!/bin/bash: このスクリプトがbashで実行されることを示します。
  2. eval $(go env): 現在のGo環境変数(GOARCH, GOOS, GOROOTなど)をスクリプトの環境にロードします。これにより、スクリプト内でこれらの変数を利用できるようになります。
  3. export NACLENV_GOARCH=$GOARCH など: Goの環境変数を、NaCl環境で利用される可能性のあるNACLENV_プレフィックスを持つ変数にエクスポートします。これは、NaClサンドボックス内で実行されるGoプログラムが、自身の実行環境に関する情報を取得できるようにするためと考えられます。
  4. export NACLENV_NACLPWD=$(pwd | sed "s;$GOROOT;/go;"): 現在の作業ディレクトリをNaClサンドボックス内のパスに変換します。$GOROOT/goに置換することで、サンドボックス内の仮想的なファイルシステムパスにマッピングしています。
  5. exec sel_ldr_x86_64 -l /dev/null -S -e "$@": この行が最も重要です。
    • exec: 現在のシェルプロセスをsel_ldr_x86_64プロセスに置き換えます。これにより、スクリプトの実行が終了すると同時にsel_ldrが起動します。
    • sel_ldr_x86_64: 64ビットNaClバイナリをロード・実行するためのNaClローダーです。
    • -l /dev/null: ロギング出力を/dev/nullにリダイレクトします。
    • -S: サンドボックスを有効にします。
    • -e "$@": スクリプトに渡されたすべての引数(Goバイナリのパスとそれに続く引数)を、sel_ldrが実行するプログラムの引数として渡します。

このスクリプトは、GoツールチェインがNaCl環境でGoバイナリを実行する際の「橋渡し」の役割を果たし、GoのビルドシステムとNaClサンドボックスの間のシームレスな連携を実現しています。

関連リンク

参考にした情報源リンク