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

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

このコミットは、Go言語のAPI定義ファイルである api/except.txt に、FreeBSD 10に特有のシステムコール関連の定数や構造体に関する例外定義を追加するものです。これにより、GoプログラムがFreeBSD 10環境で正しくシステムコールを呼び出し、OSとの互換性を保つための基盤が強化されます。

コミット

commit d30d42915ab9ae24b20674ef20a9f1eac745c714
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Tue Mar 4 09:26:28 2014 +0900

    api: add FreeBSD 10 exceptions
    
    Update #7193
    
    LGTM=minux.ma
    R=golang-codereviews, rsc, minux.ma, iant
    CC=golang-codereviews
    https://golang.org/cl/57210043

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

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

元コミット内容

api: add FreeBSD 10 exceptions

Update #7193

LGTM=minux.ma
R=golang-codereviews, rsc, minux.ma, iant
CC=golang-codereviews
https://golang.org/cl/57210043

変更の背景

Go言語の syscall パッケージは、オペレーティングシステムが提供する低レベルなシステムコールへのインターフェースを提供します。Goプログラムが様々なOSやアーキテクチャ上で正しく動作するためには、Goの syscall パッケージ内の定数、構造体のレイアウト、およびシステムコール番号などが、ターゲットOSのC言語ヘッダファイルで定義されている値と正確に一致している必要があります。

FreeBSD 10は、FreeBSDオペレーティングシステムのメジャーバージョンアップであり、これまでのバージョンと比較して、システムコールインターフェースに新たな定数、構造体の変更、あるいは既存の定数の値の変更などが導入される可能性があります。Goのツールチェーンは、api/except.txt のようなファイルを用いて、特定のOS/アーキテクチャにおけるAPIの差異や例外を管理しています。

このコミットは、FreeBSD 10のリリースに伴い、Goの syscall パッケージがFreeBSD 10の新しいAPI定義に適合するように更新する必要があったために行われました。具体的には、FreeBSD 10で導入された、または変更された可能性のあるシステムコール関連の定数や構造体の定義を api/except.txt に追加することで、GoコンパイラやリンカがFreeBSD 10向けに正しいバイナリを生成できるようにし、GoプログラムがFreeBSD 10上で安定して動作することを保証します。コミットメッセージにある Update #7193 は、この変更が特定の課題追跡システム(Issue Tracker)の項目に対応するものであることを示唆しており、FreeBSD 10への対応がGoコミュニティ内で認識されていた課題であったことが伺えます。

前提知識の解説

このコミットを理解するためには、以下の概念についての知識が役立ちます。

  1. システムコール (System Call): システムコールは、ユーザー空間で動作するプログラムが、カーネル空間で提供されるOSのサービス(ファイルI/O、メモリ管理、プロセス管理、ネットワーク通信など)を利用するための唯一の手段です。プログラムは直接ハードウェアにアクセスできないため、OSが提供するAPIを通じてこれらのサービスを要求します。Go言語では、syscall パッケージがこれらの低レベルなインターフェースを提供します。

  2. Go言語の syscall パッケージ: Goの syscall パッケージは、各オペレーティングシステム(Linux, macOS, Windows, FreeBSDなど)および各アーキテクチャ(amd64, arm, 386など)に特化したシステムコールへのバインディングを提供します。このパッケージは、OSのC言語ヘッダファイルで定義されている定数(例: O_CLOEXEC)、構造体(例: Stat_t)、および関数(例: open, read)をGoの型と関数にマッピングします。

  3. api/except.txt ファイル: Goプロジェクトでは、api/except.txt のようなファイルが、Goの標準ライブラリがサポートする各OS/アーキテクチャにおけるAPIの差異や「例外」を記録するために使用されます。これは、Goのビルドシステムが、特定の環境でGoの内部定義がOSのネイティブ定義と一致しているかを検証する際に参照されます。例えば、ある定数の値がOSのバージョンによって異なる場合、その差異がこのファイルに記述されます。これにより、Goのコンパイラやリンカは、ターゲット環境に合わせた適切なコードを生成できます。このファイルは、GoのAPI互換性チェックの一部として機能し、Goの将来のバージョンでAPIが意図せず変更されることを防ぐ役割も果たします。

  4. Cgo (GoとCの相互運用): Cgoは、GoプログラムからC言語のコードを呼び出したり、C言語のコードからGoの関数を呼び出したりするためのGoの機能です。syscall パッケージの多くの部分は、OSのネイティブAPIがC言語で提供されているため、Cgoを介して実装されています。コミットに含まれる cgo サフィックスを持つエントリ(例: freebsd-386-cgo)は、Cgoを介してアクセスされるAPI要素に関連する定義であることを示しています。また、構造体定義に見られる Pad_cgo_0 のようなフィールドは、Cgoとの相互運用において、C言語の構造体のアライメント要件を満たすためにGo側で追加されるパディングバイトを示しています。

  5. FreeBSD 10: FreeBSDは、UNIXライクなオープンソースのオペレーティングシステムです。FreeBSD 10は、2014年1月にリリースされた主要なバージョンであり、多くの新機能、パフォーマンス改善、およびAPIの変更が含まれていました。Goのようなクロスプラットフォーム言語がFreeBSD 10を完全にサポートするためには、これらの変更に適応する必要があります。

技術的詳細

このコミットは、api/except.txt ファイルに76行の新しいエントリを追加しています。これらのエントリは、FreeBSD 10の異なるアーキテクチャ(386, amd64, arm)およびCgoの有無に対応する syscall パッケージの定数と構造体に関する定義です。

追加されたエントリのパターンは以下の通りです。

  • pkg syscall (freebsd-<arch>), const <CONSTANT_NAME> = <VALUE>: 特定のFreeBSDアーキテクチャにおける syscall パッケージの定数の値を示します。
  • pkg syscall (freebsd-<arch>), const <CONSTANT_NAME> ideal-int: 特定のFreeBSDアーキテクチャにおける syscall パッケージの定数が「理想的な整数」であることを示します。これは、その定数の具体的な数値がコンパイル時に決定されることを意味する場合が多いです。
  • pkg syscall (freebsd-<arch>), type <TYPE_NAME> struct, <FIELD_NAME> <TYPE>: 特定のFreeBSDアーキテクチャにおける syscall パッケージの構造体のフィールド定義を示します。

具体的に追加された定数や構造体には、以下のようなものがあります。

  • AF_MAX (Address Family Maximum): ソケットプログラミングにおけるアドレスファミリーの最大値。
  • DLT_MATCHING_MAX (Data Link Type Maximum): パケットキャプチャライブラリ(libpcapなど)で使用されるデータリンクタイプの最大値。
  • ELAST (Error Last): システムエラー番号の最大値。
  • O_CLOEXEC (Close-on-exec flag): ファイルディスクリプタを開く際に指定するフラグで、exec システムコールが実行された際にそのファイルディスクリプタが自動的に閉じられるようにします。これは、セキュリティとリソースリーク防止のために非常に重要なフラグです。
  • BPF (Berkeley Packet Filter) 関連のioctlコマンド:
    • BIOCGRTIMEOUT: BPFデバイスの読み取りタイムアウトを取得するioctlコマンド。
    • BIOCSRTIMEOUT: BPFデバイスの読み取りタイムアウトを設定するioctlコマンド。
  • ネットワークインターフェース関連のioctlコマンド:
    • SIOCAIFADDR: インターフェースにアドレスを追加するioctlコマンド。
    • SIOCGIFSTATUS: インターフェースのステータスを取得するioctlコマンド。
    • SIOCSIFPHYADDR: インターフェースの物理アドレスを設定するioctlコマンド。
  • Capability (権限) 管理関連のシステムコール定数:
    • SYS_CAP_FCNTLS_GET, SYS_CAP_FCNTLS_LIMIT, SYS_CAP_IOCTLS_GET, SYS_CAP_IOCTLS_LIMIT, SYS_CAP_RIGHTS_GET, SYS_CAP_RIGHTS_LIMIT: これらはFreeBSDの cap_rights(2) システムコールに関連する定数で、プロセスが持つことができる権限(capabilities)を細かく制御するためのものです。これにより、サンドボックス化や最小権限の原則に基づいたアプリケーション設計が可能になります。ideal-int が付いているものは、Goのビルド時に実際の値が決定されることを示唆しています。
  • 各種構造体のサイズ:
    • SizeofBpfHdr: BPFヘッダ構造体のサイズ。
    • SizeofIfData: ネットワークインターフェースデータ構造体のサイズ。
    • SizeofIfMsghdr: ネットワークインターフェースメッセージヘッダ構造体のサイズ。
    • SizeofSockaddrDatalink: データリンク層ソケットアドレス構造体のサイズ。
    • SizeofSockaddrUnix: Unixドメインソケットアドレス構造体のサイズ。
  • TIOCTIMESTAMP: 端末(tty)のタイムスタンプを取得するioctlコマンド。
  • 構造体とパディング:
    • BpfHdr, RawSockaddrDatalink, RawSockaddrUnix, Stat_t などの構造体には、Pad_cgo_0 [X]uint8 のようなフィールドが追加されています。これらは、Cgoを介してC言語の構造体とGoの構造体を相互運用する際に、C言語の構造体のアライメント要件を満たすためにGo側で挿入されるパディングバイトです。これにより、GoとCの間でデータ構造のメモリレイアウトが一致し、データ破損を防ぎます。

これらの追加は、Goの syscall パッケージがFreeBSD 10の新しいAPIや変更されたAPIに正確に対応できるようにするために不可欠です。特に、O_CLOEXEC のような重要なフラグや、FreeBSD 10で強化されたCapability管理機能に関連する定数の追加は、GoプログラムがFreeBSD 10上でより安全かつ効率的に動作するための基盤となります。

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

変更は api/except.txt ファイルのみです。

--- a/api/except.txt
+++ b/api/except.txt
@@ -319,3 +319,79 @@ pkg syscall (openbsd-amd64-cgo), type Statfs_t struct, Pad_cgo_1 [4]uint8
 pkg syscall (openbsd-amd64-cgo), type Timespec struct, Pad_cgo_0 [4]uint8
 pkg unicode, const Version = "6.2.0"
+pkg syscall (freebsd-386), const AF_MAX = 38
+pkg syscall (freebsd-386), const DLT_MATCHING_MAX = 242
+pkg syscall (freebsd-386), const ELAST = 94
+pkg syscall (freebsd-386), const O_CLOEXEC = 0
+pkg syscall (freebsd-386-cgo), const AF_MAX = 38
+pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242
+pkg syscall (freebsd-386-cgo), const ELAST = 94
+pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0
+pkg syscall (freebsd-amd64), const AF_MAX = 38
+pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242
+pkg syscall (freebsd-amd64), const ELAST = 94
+pkg syscall (freebsd-amd64), const O_CLOEXEC = 0
+pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38
+pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242
+pkg syscall (freebsd-amd64-cgo), const ELAST = 94
+pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0
+pkg syscall (freebsd-arm), const AF_MAX = 38
+pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262
+pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085
+pkg syscall (freebsd-arm), const ELAST = 94
+pkg syscall (freebsd-arm), const O_CLOEXEC = 0
+pkg syscall (freebsd-arm), const SIOCAIFADDR = 2151967019
+pkg syscall (freebsd-arm), const SIOCGIFSTATUS = 3274991931
+pkg syscall (freebsd-arm), const SIOCSIFPHYADDR = 2151967046
+pkg syscall (freebsd-arm), const SYS_CAP_FCNTLS_GET = 537
+pkg syscall (freebsd-arm), const SYS_CAP_FCNTLS_GET ideal-int
+pkg syscall (freebsd-arm), const SYS_CAP_FCNTLS_LIMIT = 536
+pkg syscall (freebsd-arm), const SYS_CAP_FCNTLS_LIMIT ideal-int
+pkg syscall (freebsd-arm), const SYS_CAP_IOCTLS_GET = 535
+pkg syscall (freebsd-arm), const SYS_CAP_IOCTLS_GET ideal-int
+pkg syscall (freebsd-arm), const SYS_CAP_IOCTLS_LIMIT = 534
+pkg syscall (freebsd-arm), const SYS_CAP_IOCTLS_LIMIT ideal-int
+pkg syscall (freebsd-arm), const SYS_CAP_RIGHTS_GET = 515
+pkg syscall (freebsd-arm), const SYS_CAP_RIGHTS_GET ideal-int
+pkg syscall (freebsd-arm), const SYS_CAP_RIGHTS_LIMIT = 533
+pkg syscall (freebsd-arm), const SYS_CAP_RIGHTS_LIMIT ideal-int
+pkg syscall (freebsd-arm), const SizeofBpfHdr = 24
+pkg syscall (freebsd-arm), const SizeofIfData = 88
+pkg syscall (freebsd-arm), const SizeofIfMsghdr = 104
+pkg syscall (freebsd-arm), const SizeofSockaddrDatalink = 56
+pkg syscall (freebsd-arm), const SizeofSockaddrUnix = 108
+pkg syscall (freebsd-arm), const TIOCTIMESTAMP = 1074558041
+pkg syscall (freebsd-arm), type BpfHdr struct, Pad_cgo_0 [2]uint8
+pkg syscall (freebsd-arm), type RawSockaddrDatalink struct, Pad_cgo_0 [2]uint8
+pkg syscall (freebsd-arm), type RawSockaddrUnix struct, Pad_cgo_0 [2]uint8
+pkg syscall (freebsd-arm), type Stat_t struct, Pad_cgo_0 [4]uint8
+pkg syscall (freebsd-arm-cgo), const AF_MAX = 38
+pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262
+pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085
+pkg syscall (freebsd-arm-cgo), const ELAST = 94
+pkg syscall (freebsd-arm-cgo), const O_CLOEXEC = 0
+pkg syscall (freebsd-arm-cgo), const SIOCAIFADDR = 2151967019
+pkg syscall (freebsd-arm-cgo), const SIOCGIFSTATUS = 3274991931
+pkg syscall (freebsd-arm-cgo), const SIOCSIFPHYADDR = 2151967046
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_FCNTLS_GET = 537
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_FCNTLS_GET ideal-int
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_FCNTLS_LIMIT = 536
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_FCNTLS_LIMIT ideal-int
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_IOCTLS_GET = 535
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_IOCTLS_GET ideal-int
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_IOCTLS_LIMIT = 534
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_IOCTLS_LIMIT ideal-int
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_RIGHTS_GET = 515
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_RIGHTS_GET ideal-int
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_RIGHTS_LIMIT = 533
+pkg syscall (freebsd-arm-cgo), const SYS_CAP_RIGHTS_LIMIT ideal-int
+pkg syscall (freebsd-arm-cgo), const SizeofBpfHdr = 24
+pkg syscall (freebsd-arm-cgo), const SizeofIfData = 88
+pkg syscall (freebsd-arm-cgo), const SizeofIfMsghdr = 104
+pkg syscall (freebsd-arm-cgo), const SizeofSockaddrDatalink = 56
+pkg syscall (freebsd-arm-cgo), const SizeofSockaddrUnix = 108
+pkg syscall (freebsd-arm-cgo), const TIOCTIMESTAMP = 1074558041
+pkg syscall (freebsd-arm-cgo), type BpfHdr struct, Pad_cgo_0 [2]uint8
+pkg syscall (freebsd-arm-cgo), type RawSockaddrDatalink struct, Pad_cgo_0 [2]uint8
+pkg syscall (freebsd-arm-cgo), type RawSockaddrUnix struct, Pad_cgo_0 [2]uint8
+pkg syscall (freebsd-arm-cgo), type Stat_t struct, Pad_cgo_0 [4]uint8

コアとなるコードの解説

このコミットのコアとなる変更は、api/except.txt ファイルへの追記です。このファイルは、Goのビルドプロセスにおいて、特定のOSおよびアーキテクチャにおける syscall パッケージのAPI定義が、Goの内部的な期待値と一致しているかを検証するために使用されます。

追加された各行は、以下の形式でGoのAPI要素の特性を記述しています。

  • pkg syscall (freebsd-<arch>): これは、syscall パッケージが対象とするオペレーティングシステムとアーキテクチャを示します。例えば、freebsd-386 はFreeBSDの32ビットx86アーキテクチャを、freebsd-amd64 は64ビットx86アーキテクチャを、freebsd-arm はARMアーキテクチャを指します。-cgo サフィックスが付いているものは、Cgoを有効にしたビルドの場合に適用される定義です。
  • const <CONSTANT_NAME> = <VALUE>: これは、指定されたOS/アーキテクチャにおける特定の定数の期待される値を示します。Goの syscall パッケージ内の対応する定数がこの値と異なる場合、ビルド時にエラーが発生し、Goの定義がOSのネイティブ定義と同期されていないことが示されます。
  • const <CONSTANT_NAME> ideal-int: これは、その定数が「理想的な整数」として扱われることを示します。これは、Goのコンパイラがその定数の型を文脈に応じて柔軟に推論できることを意味します。また、その値がコンパイル時にターゲットOSのヘッダファイルから動的に取得される場合もあります。
  • type <TYPE_NAME> struct, <FIELD_NAME> <TYPE>: これは、指定されたOS/アーキテクチャにおける特定の構造体のフィールドの型と名前を示します。特に、Pad_cgo_X のようなフィールドは、C言語の構造体との互換性を保つためにGo側で追加されるパディングバイトを示しており、Cgoを使用する際にメモリレイアウトの不一致による問題を避けるために重要です。

これらの定義を追加することで、GoのビルドシステムはFreeBSD 10のシステムコールインターフェースの正確なスナップショットを持つことになります。これにより、Goの syscall パッケージがFreeBSD 10上で正しく機能し、GoプログラムがOSの低レベルな機能と安全かつ効率的にやり取りできるようになります。

この変更は、Go言語のクロスプラットフォーム互換性を維持し、新しいOSバージョンへの対応を確実にするための、継続的なメンテナンス作業の一環です。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード(api/except.txt の役割に関する一般的な理解)
  • FreeBSDのシステムコールおよびヘッダファイルに関する一般的な知識
  • Cgoのパディングに関する一般的な知識
  • コミットメッセージとdiffの内容
  • GitHubのGoリポジトリ
  • golang.org/cl/57210043 (Gerrit Change-ID) - 直接アクセスはできないが、Goのコードレビュープロセスを示すものとして参照。
  • Issue #7193 (GoのIssue Tracker) - 直接アクセスはできないが、関連する課題が存在することを示すものとして参照。