[インデックス 14477] ファイルの概要
このコミットは、Go言語のランタイムがFreeBSDオペレーティングシステムと連携するために使用する定義ファイル群を再生成したものです。具体的には、godefs
ツールからcgo -cdefs
ツールへの移行に伴い、FreeBSDの異なるアーキテクチャ(386, amd64, ARM)向けのCヘッダーファイルと、それに対応するGoの定義ファイルが更新されました。これにより、GoランタイムがFreeBSDのシステムコールやデータ構造をより正確かつ効率的に利用できるようになります。
コミット
commit f02cf1997d84107cbdd53967748c1d8f3a2a8577
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date: Mon Nov 26 21:29:13 2012 +0900
runtime: regenerate defs-files for freebsd
R=minux.ma, jsing
CC=golang-dev
https://golang.org/cl/6855080
---
src/pkg/runtime/defs_freebsd.go | 1 -
src/pkg/runtime/defs_freebsd_386.h | 318 ++++++++++++++++----------------
src/pkg/runtime/defs_freebsd_amd64.h | 340 +++++++++++++++++------------------
src/pkg/runtime/defs_freebsd_arm.h | 281 ++++++++++++++---------------\n src/pkg/runtime/signal_freebsd_arm.c | 20 ++-\n src/pkg/runtime/thread_freebsd.c | 6 +-\n 6 files changed, 477 insertions(+), 489 deletions(-)
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f02cf1997d84107cbdd53967748c1d8f3a2a8577
元コミット内容
このコミットの元の内容は、FreeBSD向けのGoランタイム定義ファイル群を再生成することです。これは、Goのビルドシステムとツールチェーンの進化に伴い、OSとのインターフェースを定義するメカニズムが変更された結果として行われました。具体的には、以前はgodefs
という独立したツールで生成されていた定義ファイルが、cgo
ツールの一部である-cdefs
オプションを使用して生成されるようになりました。これにより、生成されるファイルのフォーマットが統一され、GoとCの間の相互運用性定義の管理が簡素化されました。
変更の背景
Go言語は、そのランタイムが直接オペレーティングシステム(OS)のシステムコールを呼び出すことで、高いパフォーマンスと効率を実現しています。このOSとの低レベルな連携を可能にするために、Goランタイムは各OSおよびアーキテクチャ固有の定数、構造体、関数シグネチャなどの定義を必要とします。これらの定義は通常、C言語のヘッダーファイル(.h
)とGo言語のソースファイル(.go
)の形で存在します。
以前は、これらの定義ファイルを生成するためにgodefs
という専用のツールが使用されていました。しかし、Goのツールチェーンが成熟するにつれて、C言語との相互運用を扱うcgo
ツールに、この定義ファイル生成の機能が統合されることになりました。cgo -cdefs
は、GoのソースコードからCの定義を生成する機能を提供し、godefs
の役割を引き継ぎました。
このコミットは、FreeBSD環境において、この新しいcgo -cdefs
のワークフローに移行し、既存の定義ファイルを新しいツールで再生成した結果です。再生成により、ファイルの内容が最新のツールによって生成されたものに更新され、フォーマットの統一や、場合によってはOSのAPI変更への対応が行われます。
前提知識の解説
- Goランタイム (Go Runtime): Goプログラムの実行を管理する中核部分です。ガベージコレクション、ゴルーチン(軽量スレッド)のスケジューリング、メモリ管理、そしてOSとの直接的なインターフェース(システムコール)の呼び出しなどを担当します。
- システムコール (System Call): アプリケーションがOSのカーネルサービス(ファイルI/O、メモリ管理、プロセス管理など)を利用するためのインターフェースです。Goランタイムは、OSの機能を利用するために直接システムコールを呼び出します。
defs-files
: Goランタイムが特定のOSやアーキテクチャのシステムコールやデータ構造を理解し、それらと連携するために必要な定義を含むファイル群です。これらは通常、C言語のヘッダーファイル(.h
)とGo言語の型定義ファイル(.go
)で構成されます。godefs
: Go言語の初期のツールチェーンに含まれていたユーティリティで、C言語の構造体や定数定義からGo言語の対応する定義を自動生成するために使用されていました。cgo
: Go言語とC言語(およびC++)のコードを相互に呼び出すためのGoツールです。Goプログラム内でCの関数を呼び出したり、CのコードからGoの関数を呼び出したりすることを可能にします。cgo -cdefs
:cgo
ツールに新たに追加されたオプションで、godefs
の機能を置き換えるものです。Goのソースファイル(特に// #cgo CFLAGS: -D...
のようなディレクティブを含むもの)から、C言語のヘッダーファイル形式で定義を生成します。これにより、GoとCの間の型定義の同期がより密接に行われるようになりました。- FreeBSD: オープンソースのUnix系オペレーティングシステムの一つです。Go言語は、Linux、Windows、macOSなどと同様にFreeBSDも公式にサポートしています。
- アーキテクチャ (386, amd64, ARM): CPUの命令セットアーキテクチャを指します。
- 386: Intel 80386互換の32ビットアーキテクチャ(i386とも呼ばれる)。
- amd64: x86-64とも呼ばれる64ビットアーキテクチャ。現代のほとんどのデスクトップおよびサーバーCPUで採用されています。
- ARM: モバイルデバイスや組み込みシステムで広く使用されているRISCベースのアーキテクチャ。
技術的詳細
このコミットの主要な技術的変更点は、定義ファイルの生成ツールがgodefs
からcgo -cdefs
に切り替わったことです。これにより、以下の具体的な変更が見られます。
-
ヘッダーコメントの変更:
- 旧:
// godefs -f -m32 defs.c
または// MACHINE GENERATED - DO NOT EDIT.
- 新:
// Created by cgo -cdefs - DO NOT EDIT
または// cgo -cdefs defs_freebsd.go
これは、ファイルがどのツールによって生成されたかを示す明確な変更点です。DO NOT EDIT
のコメントは、これらのファイルが手動で編集されるべきではなく、ツールによって管理されるべきであることを強調しています。
- 旧:
-
定数定義のフォーマット変更:
enum
ブロック内の定数定義のフォーマットが変更されました。- 旧:
PROT_NONE = 0,
- 新:
PROT_NONE = 0x0,
値が16進数表記に統一され、タブによるインデントが導入されています。これは、生成ツールの出力スタイルの違いによるものです。
- 旧:
-
構造体定義の変更: C言語の構造体定義において、
typedef struct Name Name;
という前方宣言が追加され、その後に実際の構造体定義が続く形式になりました。また、構造体メンバーのインデントがタブに統一されています。- 例:
// 旧 typedef struct Rtprio Rtprio; struct Rtprio { uint16 type; uint16 prio; }; // 新 typedef struct Rtprio Rtprio; struct Rtprio { uint16 type; uint16 prio; };
これは、C言語の慣習に合わせたより標準的な記述方法であり、可読性の向上にも寄与します。
- 例:
-
Sigval
ユニオンの削除:src/pkg/runtime/defs_freebsd.go
および対応する.h
ファイルからSigval
ユニオンの定義が削除されました。Sigval
はシグナルハンドリングにおいて追加の情報を渡すために使用されるユニオンですが、GoランタイムがFreeBSDのシグナルを扱う方法が変更されたか、あるいはこのユニオンがGoの内部表現で直接必要なくなったことを示唆しています。代わりに、Siginfo
構造体内のsi_value
フィールドがbyte
配列として定義されています(例:byte si_value[4];
)。これは、Go側でSigval
の具体的な構造を意識せず、バイト列として扱うことで、より柔軟な対応を可能にするための変更と考えられます。 -
Mcontext
構造体の変更 (ARMアーキテクチャ):src/pkg/runtime/defs_freebsd_arm.h
において、Mcontext
構造体の定義が大きく変更されました。以前は個々のレジスタ(r0
,r1
, ...,r15
,cpsr
)が直接メンバーとして定義されていましたが、新しい定義ではこれらが__gregs
という配列にまとめられ、浮動小数点ユニット(FPU)の状態も__fpu
という配列に抽象化されました。- 旧:
uint32 r0; uint32 r1; ... uint32 cpsr;
- 新:
uint32 __gregs[17]; byte __fpu[140];
この変更は、異なるARMサブアーキテクチャやコンパイラバージョン間での互換性を高めるため、またはGoランタイムがレジスタ状態をより汎用的な方法で扱うためと考えられます。
- 旧:
-
signal_freebsd_arm.c
におけるレジスタアクセスの調整:Mcontext
構造体の変更に伴い、src/pkg/runtime/signal_freebsd_arm.c
では、既存のCコードが引き続きレジスタにアクセスできるように、新しい__gregs
配列のインデックスに対応する#define
マクロが追加されました。- 例:
#define r0 __gregs[0]
これにより、ソースコードの変更を最小限に抑えつつ、新しい構造体定義に適応しています。これは、APIの互換性を維持しつつ、内部実装を変更する一般的な手法です。
- 例:
-
ポインタ型のキャスト変更:
src/pkg/runtime/signal_freebsd_arm.c
とsrc/pkg/runtime/thread_freebsd.c
において、いくつかのポインタ型がint8*
からuint8*
やvoid*
、byte*
にキャストされるように変更されました。- 例:
st.ss_sp = (int8*)p;
からst.ss_sp = (uint8*)p;
- 例:
param.arg = m;
からparam.arg = (byte*)m;
- 例:
param.stack_base = (int8*)g->stackbase;
からparam.stack_base = (void*)g->stackbase;
- 例:
param.tls_base = (int8*)&m->tls[0];
からparam.tls_base = (void*)&m->tls[0];
これらの変更は、ThrParam
構造体のメンバーに値を割り当てる際のポインタ型のキャストを調整しています。byte
はGoにおけるバイト型であり、Cのunsigned char
に相当します。void*
はC言語において任意の型のポインタを指すことができるため、より柔軟なポインタ操作が可能になります。これらのキャスト変更は、GoとCの間のインターフェースにおける型安全性を高め、またはGoの内部的なポインタ表現とCのポインタ表現との間の整合性を確保するためのものです。
- 例:
-
パディングバイト名の変更: 構造体内のパディングバイトのメンバー名が
pad_godefs_0
からPad_cgo_0
に変更されました。これは、生成ツールがgodefs
からcgo
に変わったことを示すもう一つの痕跡です。
コアとなるコードの変更箇所
このコミットのコアとなる変更は、主に以下のファイル群に集中しています。
src/pkg/runtime/defs_freebsd.go
: Go言語側のFreeBSD定義ファイル。Sigval
型の削除が行われました。src/pkg/runtime/defs_freebsd_386.h
: FreeBSD/386アーキテクチャ向けのCヘッダー定義ファイル。src/pkg/runtime/defs_freebsd_amd64.h
: FreeBSD/amd64アーキテクチャ向けのCヘッダー定義ファイル。src/pkg/runtime/defs_freebsd_arm.h
: FreeBSD/ARMアーキテクチャ向けのCヘッダー定義ファイル。特にMcontext
構造体の変更が顕著です。src/pkg/runtime/signal_freebsd_arm.c
: FreeBSD/ARMにおけるシグナルハンドリング関連のCソースファイル。Mcontext
の変更に対応するためのレジスタマクロが追加されました。src/pkg/runtime/thread_freebsd.c
: FreeBSDにおけるスレッド関連のCソースファイル。ポインタ型のキャストが調整されました。
これらのファイルは、GoランタイムがFreeBSDの低レベルな機能(メモリ管理、シグナル処理、スレッド管理など)と直接やり取りするためのインターフェースを定義しています。
コアとなるコードの解説
src/pkg/runtime/defs_freebsd.go
-type Sigval C.union_sigval
この行の削除は、GoランタイムがFreeBSDのunion sigval
を直接Goの型としてマッピングする必要がなくなったことを示しています。これは、cgo -cdefs
による生成プロセスが、このユニオンの扱いをより抽象化された方法(例えば、バイト配列として)で処理するようになったためと考えられます。
src/pkg/runtime/defs_freebsd_arm.h
(Mcontext構造体の変更)
// 旧
struct Mcontext {
uint32 r0;
uint32 r1;
uint32 r2;
uint32 r3;
uint32 r4;
uint32 r5;
uint32 r6;
uint32 r7;
uint32 r8;
uint32 r9;
uint32 r10;
uint32 r11;
uint32 r12;
uint32 r13;
uint32 r14;
uint32 r15;
uint32 cpsr;
uint32 _pad[1+33+1]; // union __fpu
};
// 新
struct Mcontext {
uint32 __gregs[17];
byte __fpu[140];
};
この変更は、ARMアーキテクチャにおけるCPUレジスタの状態を保持するMcontext
構造体の内部表現を根本的に変更しています。以前は各レジスタが個別のフィールドとして定義されていましたが、新しいバージョンでは__gregs
という配列にまとめられています。これにより、レジスタの追加や削除があった場合でも、Mcontext
構造体自体の定義を変更することなく、配列のサイズやインデックスを調整するだけで対応できるようになり、保守性が向上します。__fpu
は浮動小数点ユニットのコンテキストを保持するためのバイト配列です。
src/pkg/runtime/signal_freebsd_arm.c
(レジスタマクロの追加)
+#define r0 __gregs[0]
+#define r1 __gregs[1]
+#define r2 __gregs[2]
+// ... (r3-r15, cpsrまで同様)
+#define cpsr __gregs[16]
// ...
void
runtime·dumpregs(Mcontext *r)
{
// r->r0, r->r1 など、既存のコードが変更なく動作するように
// 上記の#defineマクロが機能する
}
Mcontext
構造体の変更により、Cコード内で直接r->r0
のようにレジスタにアクセスしていた箇所がコンパイルエラーになるのを防ぐため、これらの#define
マクロが導入されました。これにより、r->r0
という記述はプリプロセッサによってr->__gregs[0]
に展開され、既存のコードを修正することなく新しい構造体定義に対応できます。これは、APIの互換性を維持しつつ、内部実装を変更する一般的な手法です。
src/pkg/runtime/thread_freebsd.c
(ポインタ型のキャスト変更)
// 旧
param.arg = m;
param.stack_base = (int8*)g->stackbase;
param.tls_base = (int8*)&m->tls[0];
// 新
param.arg = (byte*)m;
param.stack_base = (void*)g->stackbase;
param.tls_base = (void*)&m->tls[0];
これらの変更は、ThrParam
構造体のメンバーに値を割り当てる際のポインタ型のキャストを調整しています。
param.arg = (byte*)m;
:m
(GoのM
構造体へのポインタ)をCのbyte*
(unsigned char*
に相当)にキャストしています。これは、Goのランタイム内部でM
構造体がバイト列として扱われることを示唆しています。param.stack_base = (void*)g->stackbase;
: スタックベースポインタをint8*
からより汎用的なvoid*
にキャストしています。void*
はC言語において任意の型のポインタを指すことができるため、より柔軟なポインタ操作が可能になります。param.tls_base = (void*)&m->tls[0];
: TLS(Thread Local Storage)ベースポインタも同様にvoid*
にキャストされています。
これらのキャスト変更は、GoとCの間のインターフェースにおける型安全性を高め、またはGoの内部的なポインタ表現とCのポインタ表現との間の整合性を確保するためのものです。
関連リンク
- Go言語の公式ドキュメント: https://golang.org/doc/
- Goのランタイムに関する情報: Goのソースコードリポジトリ内の
src/runtime
ディレクトリを参照。 cgo
に関する公式ドキュメント: https://golang.org/cmd/cgo/
参考にした情報源リンク
- Go Gerrit Change-ID 6855080: https://golang.org/cl/6855080
- Go言語の
godefs
ツールの歴史とcgo -cdefs
への移行に関する議論(一般的な情報源、特定のURLは変動する可能性があるため、検索クエリを推奨): "Go godefs vs cgo -cdefs"