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

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

このコミットは、Go言語のランタイムおよびsyscallパッケージがOpenBSDオペレーティングシステムのシステムABI(Application Binary Interface)変更に対応するためのものです。具体的には、OpenBSDがtime_t型を32ビットから64ビットに拡張したことによる影響を吸収し、Goプログラムが新しいABI環境で正しく動作するように更新しています。

コミット

commit 471763f657df9bfe34c40d8483e0dd4b9c4122a6
Author: Joel Sing <jsing@google.com>
Date:   Sat Jan 11 19:00:32 2014 +1100

    runtime, syscall: update for openbsd system ABI break
    
    Update Go so that it continues to work past the OpenBSD system ABI
    break, with 64-bit time_t:
    
      http://www.openbsd.org/faq/current.html#20130813
    
    Note: this makes OpenBSD 5.5 (currently 5.4-current) the minimum
    supported release for Go.
    
    Fixes #7049.
    
    R=golang-codereviews, mikioh.mikioh
    CC=golang-codereviews
    https://golang.org/cl/13368046

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

https://github.com/golang/go/commit/471763f657df9bfe34c40d8483e0dd4b9c4122a6

元コミット内容

OpenBSDのシステムABI変更、特にtime_tの64ビット化に対応するため、Goランタイムとsyscallパッケージを更新する。これにより、OpenBSD 5.5(当時の5.4-current)がGoの最小サポートリリースとなる。

変更の背景

この変更の背景には、OpenBSDオペレーティングシステムが2013年8月13日に実施した重要なシステムABIブレークがあります。ABIブレークとは、コンパイル済みのバイナリ互換性が失われるような、システムコールやデータ構造の根本的な変更を指します。

具体的には、OpenBSDはシステム内で時刻を表現するために使用されるtime_t型を、従来の32ビットから64ビットに拡張しました。32ビットのtime_tは、2038年1月19日3時14分7秒(UTC)にオーバーフローするという「2038年問題」を抱えており、これに対処するために多くのUnix系システムが64ビットへの移行を進めていました。OpenBSDもその一環としてこの変更を行いましたが、これは既存の32ビットtime_tを前提としていたアプリケーションやライブラリにとって互換性の問題を引き起こします。

Go言語のランタイムやsyscallパッケージは、OSのシステムコールを直接呼び出したり、OSが定義するデータ構造(例えば、時刻を表すTimespecTimeval構造体、ファイルシステムの状態を表すStat_tなど)を利用したりするため、このようなABI変更に直接影響を受けます。time_tが64ビットに変わると、これらの構造体内のフィールドのサイズやオフセットが変わり、結果としてシステムコールへの引数の渡し方や戻り値の解釈がずれてしまいます。

このコミットは、GoがOpenBSD上で引き続き正しく動作するために、このABI変更に追従することを目的としています。特に、OpenBSD 5.5以降のバージョンでGoが動作するように、Goの内部実装を調整する必要がありました。

前提知識の解説

ABI (Application Binary Interface)

ABIは、オペレーティングシステムとアプリケーション、またはアプリケーションの異なるモジュール間でのバイナリレベルのインターフェースを定義するものです。これには、以下のような要素が含まれます。

  • システムコール規約: アプリケーションがOSのサービスを要求する際に、どのようにレジスタやスタックを使って引数を渡し、戻り値を受け取るか。
  • データ型サイズとアラインメント: プリミティブ型(int, long, pointerなど)のメモリ上でのサイズと、構造体内のフィールドがメモリ上でどのように配置されるか(アラインメント)。
  • 関数呼び出し規約: 関数がどのように引数を受け取り、戻り値を返すか。スタックフレームのレイアウトなど。
  • シンボル名マングリング: コンパイラが関数名や変数名をどのようにバイナリ内のシンボル名に変換するか。

ABIが変更されると、その変更以前にコンパイルされたバイナリは、新しいABIを持つシステム上で正しく動作しなくなる可能性があります。今回のケースでは、time_tのサイズ変更がデータ型サイズとアラインメントに影響を与え、結果としてシステムコール規約にも影響を及ぼしました。

time_t型と2038年問題

time_tは、Unix系システムで時刻(通常はUnixエポックからの秒数)を表現するために使われるデータ型です。歴史的に32ビット符号付き整数として実装されることが多くありました。

2038年問題は、32ビット符号付き整数で表現できる最大値(2,147,483,647)が、2038年1月19日3時14分7秒(UTC)に到達することで発生します。この時刻を超えると、32ビットtime_tはオーバーフローし、負の値として解釈されるため、時刻に関連する計算や機能が誤動作する可能性があります。これは、2000年問題と同様に、システム障害を引き起こす可能性のある重大な問題として認識されています。

この問題に対処するため、多くのOSやシステムはtime_tを64ビット整数に拡張する移行を進めています。64ビット整数であれば、現在の宇宙の年齢よりもはるかに長い期間の時刻を表現できるため、実質的にこの問題は解消されます。

OpenBSD

OpenBSDは、セキュリティを最優先事項として開発されているUnix系オペレーティングシステムです。厳格なコードレビュー、プロアクティブなセキュリティ対策、そしてクリーンなコードベースを維持することで知られています。このようなセキュリティへの強いコミットメントは、時にABIの互換性を犠牲にしてでも、より堅牢で安全なシステムを構築するという判断につながることがあります。今回のtime_tの64ビット化も、長期的なシステムの健全性を考慮した上での重要な変更でした。

Go言語のランタイムとsyscallパッケージ

  • Goランタイム: Goプログラムの実行を管理する部分です。ガベージコレクション、スケジューラ、goroutineの管理、そしてOSとの低レベルなインタラクション(システムコール呼び出しなど)を担当します。OS固有のデータ構造やシステムコール規約に関する知識を内部に持っています。
  • syscallパッケージ: GoプログラムからOSのシステムコールを直接呼び出すためのインターフェースを提供します。このパッケージはOSごとに異なる実装を持ち、各OSのシステムコール番号、データ構造、エラーコードなどをGoの型にマッピングしています。ABI変更は、このパッケージが扱うデータ構造の定義やシステムコール呼び出しの引数に直接影響を与えます。

技術的詳細

このコミットの主要な技術的変更点は、OpenBSDのtime_tが32ビットから64ビットに拡張されたことに伴う、Goランタイムとsyscallパッケージ内のデータ構造の定義およびシステムコール呼び出しの調整です。

  1. データ構造の変更:

    • src/pkg/runtime/defs_openbsd_386.h および src/pkg/runtime/defs_openbsd_amd64.h: これらのファイルは、Goランタイムが使用するOpenBSD固有のC構造体の定義を含んでいます。
      • Timespec構造体とTimeval構造体内のtv_secフィールドが、int32からint64に変更されています。これは、秒数を格納するフィールドが64ビットになったことを反映しています。
      • Kevent構造体内のdataフィールド(386アーキテクチャの場合)およびidentフィールド(amd64アーキテクチャの場合)も、関連するデータサイズ変更に合わせてint32からint64またはuint32からuint64に変更されています。
      • Sigcontext構造体内のsc_onstackフィールドが__sc_unusedに変更されています。これは、ABI変更に伴い、このフィールドがGoランタイムにとって不要になったか、別の方法で処理されるようになったことを示唆しています。
    • src/pkg/syscall/ztypes_openbsd_386.go および src/pkg/syscall/ztypes_openbsd_amd64.go: これらのファイルは、Goのsyscallパッケージが使用するOpenBSD固有のGoの型定義を含んでいます。
      • TimespecおよびTimeval構造体のSecフィールドがint32からint64に変更されています。
      • Stat_t構造体内のInoフィールド(inode番号)がuint32からuint64に変更されています。これは、ファイルシステムがより大きなinode番号をサポートするようになったことを示しています。また、Devフィールドもint32からint64に変更されています。
      • Dirent構造体内のFilenoフィールド(ディレクトリ内のファイル番号)がuint32からuint64に変更されています。
      • Kevent_t構造体内のIdentおよびDataフィールドの型が変更されています。
      • Statfs_t構造体内のF_ctimeフィールドがuint32からuint64に変更されています。
      • 各種Sizeof定数(例: SizeofIfMsghdr, SizeofRtMsghdr, SizeofRtMetrics)が、構造体サイズの変更に合わせて更新されています。
      • RtMetrics構造体内のExpireフィールドの型が変更されています。
  2. システムコール番号とアセンブリコードの調整:

    • src/pkg/runtime/sys_openbsd_386.s および src/pkg/runtime/sys_openbsd_amd64.s: これらのアセンブリファイルは、Goランタイムが直接呼び出す低レベルのシステムコールラッパーを含んでいます。
      • nanosleep, setitimer, clock_gettime, __thrsleep, keventなどのシステムコール呼び出しにおいて、使用されるシステムコール番号(AXレジスタに設定される値)が変更されています。これは、OpenBSDのABI変更により、これらのシステムコールの番号が再割り当てされたことを意味します。
      • runtime·usleep, time·now, runtime·nanotimeなどの関数で、TimespecTimeval構造体のフィールドにアクセスする際のオフセットや、64ビット値を扱うためのレジスタ操作(例: MOVLからMOVQへの変更、高位32ビットの処理)が調整されています。特に、32ビットアーキテクチャ(i386)では、64ビット値を扱うために複数のレジスタを使用する(例: DX:AX)必要があり、そのためのコードが追加されています。
    • src/pkg/syscall/zsysnum_openbsd_386.go および src/pkg/syscall/zsysnum_openbsd_amd64.go: これらのファイルは、OpenBSDのシステムコール番号の定数を定義しています。
      • 多くのシステムコール(SYS_WAIT4, SYS_GETRUSAGE, SYS_STAT, SYS_LSTAT, SYS_FSTATAT, SYS_FSTAT, SYS_GETFSSTAT, SYS_STATFS, SYS_FSTATFS, SYS_FHSTATFS, SYS_GETTIMEOFDAY, SYS_SETTIMEOFDAY, SYS_SETITIMER, SYS_GETITIMER, SYS_SELECT, SYS_KEVENT, SYS_UTIMES, SYS_FUTIMES, SYS_UTIMENSAT, SYS_FUTIMENS, SYS_CLOCK_GETTIME, SYS_CLOCK_SETTIME, SYS_CLOCK_GETRES, SYS_NANOSLEEP, SYS___THRSLEEP, SYS_GETDENTS, SYS_PPOLL, SYS_PSELECT, SYS_UTRACEなど)の番号が変更されています。これは、OpenBSDがシステムコールテーブルを再編成した結果です。
      • 一部のシステムコール(例: SYS_GETDIRENTRIES)が削除され、代わりにSYS_GETDENTSが追加されています。
  3. syscallパッケージのGoコードの変更:

    • src/pkg/syscall/syscall_openbsd.go: Getdirentries関数が削除され、代わりにgetdentsシステムコールを呼び出すGetdirentries関数が追加されています。これは、OpenBSDがディレクトリエントリーを読み取るためのシステムコールを変更したことに対応しています。
    • src/pkg/syscall/syscall_openbsd_386.go および src/pkg/syscall/syscall_openbsd_amd64.go: TimespecToNsec, NsecToTimespec, TimevalToNsec, NsecToTimevalなどの時間変換関数で、ts.Sectv.Secの型がint32からint64に変更されています。また、SetKevent関数でk.Identの型がuint32からuint64に変更されています。
    • src/pkg/syscall/zerrors_openbsd_386.go および src/pkg/syscall/zerrors_openbsd_amd64.go: 各種定数(ioctlコマンド、プロトコル番号、フラグなど)の値がOpenBSDの新しい定義に合わせて更新されています。これは、ABI変更に伴い、これらの定数の値も変更されたためです。
    • src/pkg/syscall/zsyscall_openbsd_386.go および src/pkg/syscall/zsyscall_openbsd_amd64.go: Getdirentries関数の実装が削除され、getdentsシステムコールを呼び出す新しいgetdents関数が追加されています。これは、OpenBSDのディレクトリエントリー読み取りAPIの変更に直接対応するものです。
    • src/pkg/syscall/zsysctl_openbsd.go: sysctlMib配列からいくつかのエントリが削除または変更されています。これは、OpenBSDのsysctlインターフェースで利用可能なカーネル情報の一部が変更されたことを示しています。

これらの変更は、GoがOpenBSDの新しいABIに完全に準拠し、time_tの64ビット化によって引き起こされる潜在的な互換性問題を回避するために不可欠でした。

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

このコミットにおけるコアとなるコードの変更は、主に以下のファイル群に集中しています。

  1. src/pkg/runtime/defs_openbsd_386.h および src/pkg/runtime/defs_openbsd_amd64.h:

    • Timespec構造体のtv_secフィールドの型がint32からint64へ変更。
    • Timeval構造体のtv_secフィールドの型がint32からint64へ変更。
    • Kevent構造体のdataフィールド(386)またはidentフィールド(amd64)の型が変更。
    • Sigcontext構造体のsc_onstackフィールドが__sc_unusedへ変更。
  2. src/pkg/runtime/sys_openbsd_386.s および src/pkg/runtime/sys_openbsd_amd64.s:

    • runtime·usleep, time·now, runtime·nanotime, runtime·setitimer, runtime·kevent, runtime·thrsleepなどのアセンブリ関数におけるシステムコール番号(AXレジスタの値)の変更。
    • time·nowruntime·nanotimeにおける、64ビット時刻値の処理(レジスタの利用方法、オフセットの調整)の変更。
  3. src/pkg/syscall/syscall_openbsd.go:

    • Getdirentries関数の定義が変更され、内部でgetdentsシステムコールを呼び出すように修正。
  4. src/pkg/syscall/syscall_openbsd_386.go および src/pkg/syscall/syscall_openbsd_amd64.go:

    • NsecToTimespecおよびNsecToTimeval関数におけるts.Sectv.Secへの代入がint32キャストからint64キャスト(または直接代入)へ変更。
    • SetKevent関数におけるk.Identの型がuint32からuint64へ変更。
  5. src/pkg/syscall/zerrors_openbsd_386.go および src/pkg/syscall/zerrors_openbsd_amd64.go:

    • 多数の定数値(BIOCGRTIMEOUT, BIOCSRTIMEOUT, RTM_VERSION, SIOCBRDGDADDR, SIOCBRDGSADDR, TIOCGTSTAMPなど)の変更。
  6. src/pkg/syscall/zsyscall_openbsd_386.go および src/pkg/syscall/zsyscall_openbsd_amd64.go:

    • Getdirentries関数の削除と、getdents関数の追加。
    • Syscall関数の引数として渡されるシステムコール番号の変更。
  7. src/pkg/syscall/zsysnum_openbsd_386.go および src/pkg/syscall/zsysnum_openbsd_amd64.go:

    • OpenBSDのシステムコール番号の定数定義が大幅に更新。多くのシステムコール番号が変更され、一部のシステムコールが追加または削除されています。
  8. src/pkg/syscall/ztypes_openbsd_386.go および src/pkg/syscall/ztypes_openbsd_amd64.go:

    • Timespec, Timeval, Stat_t, Dirent, Kevent_t, Statfs_t, RtMetricsなどの構造体内のフィールドの型(int32からint64uint32からuint64など)およびオフセットの変更。
    • SizeofIfMsghdr, SizeofIfData, SizeofRtMsghdr, SizeofRtMetricsなどのサイズ定数の更新。

コアとなるコードの解説

このコミットの核心は、OpenBSDのABI変更、特にtime_tの64ビット化にGoが適応することです。

  1. データ型のサイズ変更への対応:

    • TimespecTimevalといった時刻関連の構造体は、OSのシステムコールで時刻情報をやり取りする際に頻繁に使用されます。これらの構造体内の秒を表すフィールド(tv_secSec)が32ビットから64ビットに変更されたため、Goのランタイムとsyscallパッケージ内の対応するGoの型定義もint32からint64に更新されました。これにより、GoプログラムがOSから取得する時刻情報が正しく解釈され、2038年問題の影響を受けなくなります。
    • Stat_t(ファイルの状態)、Dirent(ディレクトリエントリー)、Kevent_t(kqueueイベント)などの構造体も、内部のフィールド(inode番号、ファイル番号、イベントデータなど)が64ビットに拡張されたため、Goの型定義が更新されています。これにより、Goがファイルシステムやイベント通知システムと正しく連携できるようになります。
    • これらの構造体サイズの変更は、Sizeof定数の更新にもつながり、メモリ割り当てやデータコピーの際に正しいサイズが使用されることを保証します。
  2. システムコール番号の変更への対応:

    • OpenBSDのABI変更では、既存のシステムコールの番号が再割り当てされたり、新しいシステムコールが導入されたりすることがあります。Goのランタイムは、アセンブリコードを通じて直接システムコールを呼び出すため、これらの番号の変更に追従する必要があります。
    • src/pkg/runtime/sys_openbsd_*.sファイルでは、INT $0x80(i386)やSYSCALL(amd64)命令の直前にAXレジスタに設定されるシステムコール番号が、OpenBSDの新しい定義に合わせて更新されています。
    • src/pkg/syscall/zsysnum_openbsd_*.goファイルでは、Goのコードからシステムコールを呼び出す際に使用される定数(SYS_NANOSLEEPなど)が、新しいシステムコール番号に更新されています。これにより、Goプログラムが正しいシステムコールを呼び出すことが保証されます。
  3. システムコールAPIの変更への対応:

    • Getdirentriesからgetdentsへの変更は、ディレクトリの内容を読み取るためのシステムコールAPIが変更されたことを示しています。Goのsyscallパッケージは、この新しいAPIに合わせてGetdirentries関数の実装を更新し、内部でgetdentsシステムコールを呼び出すように変更されました。これにより、GoプログラムがOpenBSDの新しいディレクトリ読み取りメカニズムを正しく利用できるようになります。
  4. アセンブリコードでの64ビット値の処理:

    • 特に32ビットアーキテクチャ(i386)では、64ビット値を扱うために複数の32ビットレジスタ(例: DX:AX)を組み合わせて使用する必要があります。runtime·nanotimeなどの関数では、tv_secが64ビットになったことで、秒とナノ秒を組み合わせてナノ秒単位の合計時間を計算する際に、64ビット演算を正しく行うためのアセンブリ命令が追加・修正されています。これにより、時刻計算の精度と正確性が維持されます。

これらの変更は、GoがOpenBSDの進化するシステム環境に適合し、長期的な互換性と安定性を確保するために不可欠なものです。

関連リンク

参考にした情報源リンク

  • OpenBSD公式ドキュメント
  • Go言語のソースコード
  • ABI (Application Binary Interface) に関する一般的な情報源 (例: Wikipedia)
  • 2038年問題に関する情報源 (例: Wikipedia)
  • Unix系システムのシステムコールに関する情報源
  • アセンブリ言語(x86/x64)の基本に関する情報源

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

このコミットは、Go言語のランタイムおよびsyscallパッケージがOpenBSDオペレーティングシステムのシステムABI(Application Binary Interface)変更に対応するためのものです。具体的には、OpenBSDがtime_t型を32ビットから64ビットに拡張したことによる影響を吸収し、Goプログラムが新しいABI環境で正しく動作するように更新しています。

コミット

commit 471763f657df9bfe34c40d8483e0dd4b9c4122a6
Author: Joel Sing <jsing@google.com>
Date:   Sat Jan 11 19:00:32 2014 +1100

    runtime, syscall: update for openbsd system ABI break
    
    Update Go so that it continues to work past the OpenBSD system ABI
    break, with 64-bit time_t:
    
      http://www.openbsd.org/faq/current.html#20130813
    
    Note: this makes OpenBSD 5.5 (currently 5.4-current) the minimum
    supported release for Go.
    
    Fixes #7049.
    
    R=golang-codereviews, mikioh.mikioh
    CC=golang-codereviews
    https://golang.org/cl/13368046

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

https://github.com/golang/go/commit/471763f657df9bfe34c40d8483e0dd4b9c4122a6

元コミット内容

OpenBSDのシステムABI変更、特にtime_tの64ビット化に対応するため、Goランタイムとsyscallパッケージを更新する。これにより、OpenBSD 5.5(当時の5.4-current)がGoの最小サポートリリースとなる。

変更の背景

この変更の背景には、OpenBSDオペレーティングシステムが2013年8月13日に実施した重要なシステムABIブレークがあります。ABIブレークとは、コンパイル済みのバイナリ互換性が失われるような、システムコールやデータ構造の根本的な変更を指します。

具体的には、OpenBSDはシステム内で時刻を表現するために使用されるtime_t型を、従来の32ビットから64ビットに拡張しました。32ビットのtime_tは、2038年1月19日3時14分7秒(UTC)にオーバーフローするという「2038年問題」を抱えており、これに対処するために多くのUnix系システムが64ビットへの移行を進めていました。OpenBSDもその一環としてこの変更を行いましたが、これは既存の32ビットtime_tを前提としていたアプリケーションやライブラリにとって互換性の問題を引き起こします。

Go言語のランタイムやsyscallパッケージは、OSのシステムコールを直接呼び出したり、OSが定義するデータ構造(例えば、時刻を表すTimespecTimeval構造体、ファイルシステムの状態を表すStat_tなど)を利用したりするため、このようなABI変更に直接影響を受けます。time_tが64ビットに変わると、これらの構造体内のフィールドのサイズやオフセットが変わり、結果としてシステムコールへの引数の渡し方や戻り値の解釈がずれてしまいます。

このコミットは、GoがOpenBSD上で引き続き正しく動作するために、このABI変更に追従することを目的としています。特に、OpenBSD 5.5以降のバージョンでGoが動作するように、Goの内部実装を調整する必要がありました。

前提知識の解説

ABI (Application Binary Interface)

ABIは、オペレーティングシステムとアプリケーション、またはアプリケーションの異なるモジュール間でのバイナリレベルのインターフェースを定義するものです。これには、以下のような要素が含まれます。

  • システムコール規約: アプリケーションがOSのサービスを要求する際に、どのようにレジスタやスタックを使って引数を渡し、戻り値を受け取るか。
  • データ型サイズとアラインメント: プリミティブ型(int, long, pointerなど)のメモリ上でのサイズと、構造体内のフィールドがメモリ上でどのように配置されるか(アラインメント)。
  • 関数呼び出し規約: 関数がどのように引数を受け取り、戻り値を返すか。スタックフレームのレイアウトなど。
  • シンボル名マングリング: コンパイラが関数名や変数名をどのようにバイナリ内のシンボル名に変換するか。

ABIが変更されると、その変更以前にコンパイルされたバイナリは、新しいABIを持つシステム上で正しく動作しなくなる可能性があります。今回のケースでは、time_tのサイズ変更がデータ型サイズとアラインメントに影響を与え、結果としてシステムコール規約にも影響を及ぼしました。

time_t型と2038年問題

time_tは、Unix系システムで時刻(通常はUnixエポックからの秒数)を表現するために使われるデータ型です。歴史的に32ビット符号付き整数として実装されることが多くありました。

2038年問題は、32ビット符号付き整数で表現できる最大値(2,147,483,647)が、2038年1月19日3時14分7秒(UTC)に到達することで発生します。この時刻を超えると、32ビットtime_tはオーバーフローし、負の値として解釈されるため、時刻に関連する計算や機能が誤動作する可能性があります。これは、2000年問題と同様に、システム障害を引き起こす可能性のある重大な問題として認識されています。

この問題に対処するため、多くのOSやシステムはtime_tを64ビット整数に拡張する移行を進めています。64ビット整数であれば、現在の宇宙の年齢よりもはるかに長い期間の時刻を表現できるため、実質的にこの問題は解消されます。

OpenBSD

OpenBSDは、セキュリティを最優先事項として開発されているUnix系オペレーティングシステムです。厳格なコードレビュー、プロアクティブなセキュリティ対策、そしてクリーンなコードベースを維持することで知られています。このようなセキュリティへの強いコミットメントは、時にABIの互換性を犠牲にしてでも、より堅牢で安全なシステムを構築するという判断につながることがあります。今回のtime_tの64ビット化も、長期的なシステムの健全性を考慮した上での重要な変更でした。

Go言語のランタイムとsyscallパッケージ

  • Goランタイム: Goプログラムの実行を管理する部分です。ガベージコレクション、スケジューラ、goroutineの管理、そしてOSとの低レベルなインタラクション(システムコール呼び出しなど)を担当します。OS固有のデータ構造やシステムコール規約に関する知識を内部に持っています。
  • syscallパッケージ: GoプログラムからOSのシステムコールを直接呼び出すためのインターフェースを提供します。このパッケージはOSごとに異なる実装を持ち、各OSのシステムコール番号、データ構造、エラーコードなどをGoの型にマッピングしています。ABI変更は、このパッケージが扱うデータ構造の定義やシステムコール呼び出しの引数に直接影響を与えます。

技術的詳細

このコミットの主要な技術的変更点と、OpenBSDのtime_tが32ビットから64ビットに拡張されたことに伴う、Goランタイムとsyscallパッケージ内のデータ構造の定義およびシステムコール呼び出しの調整です。

  1. データ構造の変更:

    • src/pkg/runtime/defs_openbsd_386.h および src/pkg/runtime/defs_openbsd_amd64.h: これらのファイルは、Goランタイムが使用するOpenBSD固有のC構造体の定義を含んでいます。
      • Timespec構造体とTimeval構造体内のtv_secフィールドが、int32からint64に変更されています。これは、秒数を格納するフィールドが64ビットになったことを反映しています。
      • Kevent構造体内のdataフィールド(386アーキテクチャの場合)およびidentフィールド(amd64アーキテクチャの場合)も、関連するデータサイズ変更に合わせてint32からint64またはuint32からuint64に変更されています。
      • Sigcontext構造体内のsc_onstackフィールドが__sc_unusedに変更されています。これは、ABI変更に伴い、このフィールドがGoランタイムにとって不要になったか、別の方法で処理されるようになったことを示唆しています。
    • src/pkg/syscall/ztypes_openbsd_386.go および src/pkg/syscall/ztypes_openbsd_amd64.go: これらのファイルは、Goのsyscallパッケージが使用するOpenBSD固有のGoの型定義を含んでいます。
      • TimespecおよびTimeval構造体のSecフィールドがint32からint64に変更されています。
      • Stat_t構造体内のInoフィールド(inode番号)がuint32からuint64に変更されています。これは、ファイルシステムがより大きなinode番号をサポートするようになったことを示しています。また、Devフィールドもint32からint64に変更されています。
      • Dirent構造体内のFilenoフィールド(ディレクトリ内のファイル番号)がuint32からuint64に変更されています。
      • Kevent_t構造体内のIdentおよびDataフィールドの型が変更されています。
      • Statfs_t構造体内のF_ctimeフィールドがuint32からuint64に変更されています。
      • 各種Sizeof定数(例: SizeofIfMsghdr, SizeofRtMsghdr, SizeofRtMetrics)が、構造体サイズの変更に合わせて更新されています。
      • RtMetrics構造体内のExpireフィールドの型が変更されています。
  2. システムコール番号とアセンブリコードの調整:

    • src/pkg/runtime/sys_openbsd_386.s および src/pkg/runtime/sys_openbsd_amd64.s: これらのアセンブリファイルは、Goランタイムが直接呼び出す低レベルのシステムコールラッパーを含んでいます。
      • nanosleep, setitimer, clock_gettime, __thrsleep, keventなどのシステムコール呼び出しにおいて、使用されるシステムコール番号(AXレジスタに設定される値)が変更されています。これは、OpenBSDのABI変更により、これらのシステムコールの番号が再割り当てされたことを意味します。
      • runtime·usleep, time·now, runtime·nanotimeなどの関数で、TimespecTimeval構造体のフィールドにアクセスする際のオフセットや、64ビット値を扱うためのレジスタ操作(例: MOVLからMOVQへの変更、高位32ビットの処理)が調整されています。特に、32ビットアーキテクチャ(i386)では、64ビット値を扱うために複数のレジスタを使用する(例: DX:AX)必要があり、そのためのコードが追加されています。
    • src/pkg/syscall/zsysnum_openbsd_386.go および src/pkg/syscall/zsysnum_openbsd_amd64.go: これらのファイルは、OpenBSDのシステムコール番号の定数を定義しています。
      • 多くのシステムコール(SYS_WAIT4, SYS_GETRUSAGE, SYS_STAT, SYS_LSTAT, SYS_FSTATAT, SYS_FSTAT, SYS_GETFSSTAT, SYS_STATFS, SYS_FSTATFS, SYS_FHSTATFS, SYS_GETTIMEOFDAY, SYS_SETTIMEOFDAY, SYS_SETITIMER, SYS_GETITIMER, SYS_SELECT, SYS_KEVENT, SYS_UTIMES, SYS_FUTIMES, SYS_UTIMENSAT, SYS_FUTIMENS, SYS_CLOCK_GETTIME, SYS_CLOCK_SETTIME, SYS_CLOCK_GETRES, SYS_NANOSLEEP, SYS___THRSLEEP, SYS_GETDENTS, SYS_PPOLL, SYS_PSELECT, SYS_UTRACEなど)の番号が変更されています。これは、OpenBSDがシステムコールテーブルを再編成した結果です。
      • 一部のシステムコール(例: SYS_GETDIRENTRIES)が削除され、代わりにSYS_GETDENTSが追加されています。
  3. syscallパッケージのGoコードの変更:

    • src/pkg/syscall/syscall_openbsd.go: Getdirentries関数が削除され、代わりにgetdentsシステムコールを呼び出すGetdirentries関数が追加されています。これは、OpenBSDがディレクトリエントリーを読み取るためのシステムコールを変更したことに対応しています。
    • src/pkg/syscall/syscall_openbsd_386.go および src/pkg/syscall/syscall_openbsd_amd64.go: TimespecToNsec, NsecToTimespec, TimevalToNsec, NsecToTimevalなどの時間変換関数で、ts.Sectv.Secの型がint32からint64に変更されています。また、SetKevent関数でk.Identの型がuint32からuint64に変更されています。
    • src/pkg/syscall/zerrors_openbsd_386.go および src/pkg/syscall/zerrors_openbsd_amd64.go: 各種定数(ioctlコマンド、プロトコル番号、フラグなど)の値がOpenBSDの新しい定義に合わせて更新されています。これは、ABI変更に伴い、これらの定数の値も変更されたためです。
    • src/pkg/syscall/zsyscall_openbsd_386.go および src/pkg/syscall/zsyscall_openbsd_amd64.go: Getdirentries関数の実装が削除され、getdentsシステムコールを呼び出す新しいgetdents関数が追加されています。これは、OpenBSDのディレクトリエントリー読み取りAPIの変更に直接対応するものです。
    • src/pkg/syscall/zsysctl_openbsd.go: sysctlMib配列からいくつかのエントリが削除または変更されています。これは、OpenBSDのsysctlインターフェースで利用可能なカーネル情報の一部が変更されたことを示しています。

これらの変更は、GoがOpenBSDの新しいABIに完全に準拠し、time_tの64ビット化によって引き起こされる潜在的な互換性問題を回避するために不可欠でした。

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

このコミットにおけるコアとなるコードの変更は、主に以下のファイル群に集中しています。

  1. src/pkg/runtime/defs_openbsd_386.h および src/pkg/runtime/defs_openbsd_amd64.h:

    • Timespec構造体のtv_secフィールドの型がint32からint64へ変更。
    • Timeval構造体のtv_secフィールドの型がint32からint64へ変更。
    • Kevent構造体のdataフィールド(386)またはidentフィールド(amd64)の型が変更。
    • Sigcontext構造体のsc_onstackフィールドが__sc_unusedへ変更。
  2. src/pkg/runtime/sys_openbsd_386.s および src/pkg/runtime/sys_openbsd_amd64.s:

    • runtime·usleep, time·now, runtime·nanotime, runtime·setitimer, runtime·kevent, runtime·thrsleepなどのアセンブリ関数におけるシステムコール番号(AXレジスタの値)の変更。
    • time·nowruntime·nanotimeにおける、64ビット時刻値の処理(レジスタの利用方法、オフセットの調整)の変更。
  3. src/pkg/syscall/syscall_openbsd.go:

    • Getdirentries関数の定義が変更され、内部でgetdentsシステムコールを呼び出すように修正。
  4. src/pkg/syscall/syscall_openbsd_386.go および src/pkg/syscall/syscall_openbsd_amd64.go:

    • NsecToTimespecおよびNsecToTimeval関数におけるts.Sectv.Secへの代入がint32キャストからint64キャスト(または直接代入)へ変更。
    • SetKevent関数におけるk.Identの型がuint32からuint64へ変更。
  5. src/pkg/syscall/zerrors_openbsd_386.go および src/pkg/syscall/zerrors_openbsd_amd64.go:

    • 多数の定数値(BIOCGRTIMEOUT, BIOCSRTIMEOUT, RTM_VERSION, SIOCBRDGDADDR, SIOCBRDGSADDR, TIOCGTSTAMPなど)の変更。
  6. src/pkg/syscall/zsyscall_openbsd_386.go および src/pkg/syscall/zsyscall_openbsd_amd64.go:

    • Getdirentries関数の削除と、getdents関数の追加。
    • Syscall関数の引数として渡されるシステムコール番号の変更。
  7. src/pkg/syscall/zsysnum_openbsd_386.go および src/pkg/syscall/zsysnum_openbsd_amd64.go:

    • OpenBSDのシステムコール番号の定数定義が大幅に更新。多くのシステムコール番号が変更され、一部のシステムコールが追加または削除されています。
  8. src/pkg/syscall/ztypes_openbsd_386.go および src/pkg/syscall/ztypes_openbsd_amd64.go:

    • Timespec, Timeval, Stat_t, Dirent, Kevent_t, Statfs_t, RtMetricsなどの構造体内のフィールドの型(int32からint64uint32からuint64など)およびオフセットの変更。
    • SizeofIfMsghdr, SizeofIfData, SizeofRtMsghdr, SizeofRtMetricsなどのサイズ定数の更新。

コアとなるコードの解説

このコミットの核心は、OpenBSDのABI変更、特にtime_tの64ビット化にGoが適応することです。

  1. データ型のサイズ変更への対応:

    • TimespecTimevalといった時刻関連の構造体は、OSのシステムコールで時刻情報をやり取りする際に頻繁に使用されます。これらの構造体内の秒を表すフィールド(tv_secSec)が32ビットから64ビットに変更されたため、Goのランタイムとsyscallパッケージ内の対応するGoの型定義もint32からint64に更新されました。これにより、GoプログラムがOSから取得する時刻情報が正しく解釈され、2038年問題の影響を受けなくなります。
    • Stat_t(ファイルの状態)、Dirent(ディレクトリエントリー)、Kevent_t(kqueueイベント)などの構造体も、内部のフィールド(inode番号、ファイル番号、イベントデータなど)が64ビットに拡張されたため、Goの型定義が更新されています。これにより、Goがファイルシステムやイベント通知システムと正しく連携できるようになります。
    • これらの構造体サイズの変更は、Sizeof定数の更新にもつながり、メモリ割り当てやデータコピーの際に正しいサイズが使用されることを保証します。
  2. システムコール番号の変更への対応:

    • OpenBSDのABI変更では、既存のシステムコールの番号が再割り当てされたり、新しいシステムコールが導入されたりすることがあります。Goのランタイムは、アセンブリコードを通じて直接システムコールを呼び出すため、これらの番号の変更に追従する必要があります。
    • src/pkg/runtime/sys_openbsd_*.sファイルでは、INT $0x80(i386)やSYSCALL(amd64)命令の直前にAXレジスタに設定されるシステムコール番号が、OpenBSDの新しい定義に合わせて更新されています。
    • src/pkg/syscall/zsysnum_openbsd_*.goファイルでは、Goのコードからシステムコールを呼び出す際に使用される定数(SYS_NANOSLEEPなど)が、新しいシステムコール番号に更新されています。これにより、Goプログラムが正しいシステムコールを呼び出すことが保証されます。
  3. システムコールAPIの変更への対応:

    • Getdirentriesからgetdentsへの変更は、ディレクトリの内容を読み取るためのシステムコールAPIが変更されたことを示しています。Goのsyscallパッケージは、この新しいAPIに合わせてGetdirentries関数の実装を更新し、内部でgetdentsシステムコールを呼び出すように変更されました。これにより、GoプログラムがOpenBSDの新しいディレクトリ読み取りメカニズムを正しく利用できるようになります。
  4. アセンブリコードでの64ビット値の処理:

    • 特に32ビットアーキテクチャ(i386)では、64ビット値を扱うために複数の32ビットレジスタ(例: DX:AX)を組み合わせて使用する必要があります。runtime·nanotimeなどの関数では、tv_secが64ビットになったことで、秒とナノ秒を組み合わせてナノ秒単位の合計時間を計算する際に、64ビット演算を正しく行うためのアセンブリ命令が追加・修正されています。これにより、時刻計算の精度と正確性が維持されます。

これらの変更は、GoがOpenBSDの進化するシステム環境に適合し、長期的な互換性と安定性を確保するために不可欠なものです。

関連リンク

参考にした情報源リンク

  • OpenBSD公式ドキュメント
  • Go言語のソースコード
  • ABI (Application Binary Interface) に関する一般的な情報源 (例: Wikipedia)
  • 2038年問題に関する情報源 (例: Wikipedia)
  • Unix系システムのシステムコールに関する情報源
  • アセンブリ言語(x86/x64)の基本に関する情報源