[インデックス 15655] ファイルの概要
このコミットは、Go言語のsyscall
パッケージにおいて、FreeBSDオペレーティングシステム向けのメモリ保護(PROT_*
)およびメモリマッピング(MAP_*
)に関連する定数を追加するものです。これにより、GoプログラムがFreeBSD上でmmap
やmprotect
といったシステムコールをより適切に利用できるようになります。具体的には、src/pkg/syscall/mkerrors.sh
スクリプトが更新され、FreeBSDのヘッダーファイルからこれらの定数が自動生成されるようになりました。影響を受けるファイルは、zerrors_freebsd_386.go
、zerrors_freebsd_amd64.go
、zerrors_freebsd_arm.go
など、FreeBSDの各アーキテクチャ向けの定数定義ファイルです。
コミット
commit 9dd92d522ff771ec4434952ab44660fa1f13b846
Author: Dave Cheney <dave@cheney.net>
Date: Sat Mar 9 16:25:30 2013 +1100
syscall: add PROT_* and MAP_* constants to freebsd
Update #4929
Regenerated from FreeBSD-9.1 for amd64 and 386, FreeBSD-CURRENT for arm.
R=devon.odell, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7438053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/9dd92d522ff771ec4434952ab44660fa1f13b846
元コミット内容
syscall: add PROT_* and MAP_* constants to freebsd
Update #4929
Regenerated from FreeBSD-9.1 for amd64 and 386, FreeBSD-CURRENT for arm.
変更の背景
Go言語のsyscall
パッケージは、Goプログラムがオペレーティングシステム(OS)のシステムコールを直接呼び出すためのインターフェースを提供します。これにより、OS固有の機能や低レベルな操作が可能になります。しかし、特定のOSやアーキテクチャにおいて、必要な定数やシステムコール定義が不足している場合があります。
このコミットの背景には、GoプログラムがFreeBSD上でメモリマッピング(mmap
)やメモリ保護(mprotect
)といったシステムコールを正確に利用するために必要なPROT_*
(メモリ保護フラグ)およびMAP_*
(メモリマッピングフラグ)定数が、syscall
パッケージのFreeBSD向け定義に欠けていたという問題があります。これらの定数が不足していると、GoプログラムからFreeBSDのメモリ管理機能を適切に制御することができませんでした。
コミットメッセージにあるUpdate #4929
は、GoのIssueトラッカーにおけるIssue 4929: syscall: add PROT_, MAP_ constants to freebsdに対応しています。このIssueでは、FreeBSDのmmap(2)
およびmprotect(2)
システムコールで使用される定数がGoのsyscall
パッケージに存在しないことが報告されており、その追加が求められていました。
前提知識の解説
システムコール (System Call)
システムコールは、ユーザー空間で実行されるプログラムが、カーネル空間で提供されるOSのサービスを利用するためのインターフェースです。ファイルI/O、プロセス管理、メモリ管理、ネットワーク通信など、OSが提供するほとんどの機能はシステムコールを通じてアクセスされます。Go言語のsyscall
パッケージは、これらのシステムコールをGoプログラムから直接呼び出すための低レベルなAPIを提供します。
mmap
とmprotect
システムコール
mmap(2)
: メモリマップドファイル(memory-mapped file)を作成するためのシステムコールです。ファイルの内容をプロセスのアドレス空間に直接マッピングすることで、ファイルI/Oを通常のメモリアクセスとして扱うことができます。これにより、ファイルの内容を読み書きする際に、read()
やwrite()
のようなシステムコールを介さずに、ポインタを介したメモリ操作で直接アクセスできるようになり、効率的なデータ処理が可能になります。また、ファイルだけでなく、匿名メモリ領域(ファイルに関連付けられていないメモリ領域)を確保するためにも使用されます。mprotect(2)
: プロセスのアドレス空間内の指定されたメモリ領域の保護属性を変更するためのシステムコールです。メモリ領域を読み取り可能(PROT_READ
)、書き込み可能(PROT_WRITE
)、実行可能(PROT_EXEC
)、またはアクセス不可(PROT_NONE
)に設定することができます。これは、セキュリティの強化や、JITコンパイラなどで動的に生成されたコードの実行を許可する際などに利用されます。
PROT_*
定数
PROT_*
定数は、mmap
やmprotect
システムコールでメモリ領域に設定する保護属性を定義します。
PROT_NONE
: アクセス不可。PROT_READ
: 読み取り可能。PROT_WRITE
: 書き込み可能。PROT_EXEC
: 実行可能。
これらの定数はビットフラグとして組み合わせて使用できます(例: PROT_READ | PROT_WRITE
)。
MAP_*
定数
MAP_*
定数は、mmap
システムコールでメモリ領域をマッピングする際の動作を制御するフラグです。
MAP_SHARED
: マッピングされたメモリ領域への変更が、そのメモリ領域を共有する他のプロセスや、元のファイルに反映されることを意味します。MAP_PRIVATE
: マッピングされたメモリ領域への変更が、呼び出し元のプロセスにのみ影響し、他のプロセスや元のファイルには反映されないことを意味します。これは「コピーオンライト」メカニズムによって実現されます。MAP_ANON
またはMAP_ANONYMOUS
: ファイルではなく、匿名メモリ領域をマッピングすることを示します。これは、プロセスが共有メモリやプライベートなヒープ領域を確保する際によく使用されます。MAP_FIXED
: 指定されたアドレスに正確にマッピングすることを試みます。MAP_STACK
: スタック領域として使用されるメモリ領域をマッピングすることを示します。
Goのsyscall
パッケージと定数生成
Goのsyscall
パッケージは、各OSおよびアーキテクチャ固有のシステムコール定数や構造体を定義しています。これらの定数は、手動で記述されるのではなく、通常はOSのCヘッダーファイルから自動生成されます。これは、OSのバージョンアップやパッチによって定数の値が変更された場合に、手動でGoのコードを更新する手間を省き、正確性を保つためです。
Goのソースコード内には、mkerrors.sh
やmksyscall.sh
といったスクリプトが存在し、これらがCヘッダーファイルを解析してGoの定数定義ファイルを生成します。生成されたファイルは、通常zerrors_*.go
やzsysnum_*.go
といった命名規則に従います。
クロスコンパイルとアーキテクチャ固有の定数
Goはクロスコンパイルを強力にサポートしており、あるOS/アーキテクチャ上で別のOS/アーキテクチャ向けのバイナリを生成できます。システムコール定数はOSだけでなく、CPUアーキテクチャ(例: amd64, 386, arm)によっても値が異なる場合があります。そのため、syscall
パッケージでは、各OSとアーキテクチャの組み合わせごとに異なる定数定義ファイル(例: zerrors_freebsd_amd64.go
, zerrors_freebsd_386.go
, zerrors_freebsd_arm.go
)が用意されています。
技術的詳細
このコミットの主要な技術的変更点は、FreeBSD向けのPROT_*
およびMAP_*
定数をGoのsyscall
パッケージに追加することです。これは、src/pkg/syscall/mkerrors.sh
スクリプトの変更と、それによって再生成されたFreeBSD固有の定数定義ファイルによって実現されています。
-
mkerrors.sh
の変更:mkerrors.sh
スクリプトは、Goのsyscall
パッケージで利用されるOS固有の定数をCヘッダーファイルから抽出・生成するためのシェルスクリプトです。このコミットでは、mkerrors.sh
内のincludes_FreeBSD
変数に、FreeBSDのsys/mman.h
ヘッダーファイルが追加されました。sys/mman.h
は、mmap
やmprotect
システムコールに関連する定数(PROT_*
,MAP_*
など)を定義しているヘッダーファイルです。このヘッダーファイルがmkerrors.sh
の処理対象に追加されたことで、スクリプトが実行される際にこれらの定数がGoのコードとして自動生成されるようになります。 -
定数定義ファイルの再生成:
mkerrors.sh
の変更後、FreeBSDの各アーキテクチャ(amd64, 386, arm)向けに以下のファイルが再生成されました。src/pkg/syscall/zerrors_freebsd_386.go
src/pkg/syscall/zerrors_freebsd_amd64.go
src/pkg/syscall/zerrors_freebsd_arm.go
これらのファイルには、
PROT_EXEC
,PROT_NONE
,PROT_READ
,PROT_WRITE
といったPROT_*
定数と、MAP_ANON
,MAP_ANONYMOUS
,MAP_COPY
,MAP_FILE
,MAP_FIXED
,MAP_PRIVATE
,MAP_SHARED
,MAP_STACK
といったMAP_*
定数が追加されています。これらの定数は、FreeBSDのシステムヘッダーファイルで定義されている値に対応しています。また、これらの主要な定数以外にも、FreeBSDのバージョン9.1(amd64および386向け)とFreeBSD-CURRENT(arm向け)から、他の多くのシステムコール関連定数(例:
B*
、BIOC*
、BPF_T_*
、DLT_*
、IFF_*
、IFT_*
、IPPROTO_*
、MADV_*
、MSG_*
、MS_*
、NET_RT_*
、NOTE_*
、O_*
、RLIMIT_*
、RT_*
、RUSAGE_*
、SIOC*
、SO_*
、TCP_*
、TIOC*
、V*
、W*
など)が追加または更新されています。これは、mkerrors.sh
が広範な定数を抽出する能力を持っているためです。 -
zsysnum_freebsd_*.go
の変更:zsysnum_freebsd_386.go
,zsysnum_freebsd_amd64.go
,zsysnum_freebsd_arm.go
ファイルも更新されています。これらのファイルはシステムコール番号を定義しており、このコミットでは新しいシステムコール(例:SYS_CLOCK_GETCPUCLOCKID2
,SYS_WAIT6
)や既存のシステムコールの引数型(SYS_CAP_NEW
のu_int64_t
からuint64_t
への変更)が反映されています。これは、FreeBSDのシステムコールインターフェースの進化に対応するためのものです。
この変更により、GoプログラムはFreeBSD上でメモリマッピングやメモリ保護を必要とする高度な操作を、Goのsyscall
パッケージを通じて直接、かつ正確に行えるようになります。
コアとなるコードの変更箇所
このコミットで変更された主要なファイルは以下の通りです。
src/pkg/syscall/mkerrors.sh
: 定数生成スクリプトsrc/pkg/syscall/zerrors_freebsd_386.go
: FreeBSD/386アーキテクチャ向けエラー・定数定義src/pkg/syscall/zerrors_freebsd_amd64.go
: FreeBSD/amd64アーキテクチャ向けエラー・定数定義src/pkg/syscall/zerrors_freebsd_arm.go
: FreeBSD/armアーキテクチャ向けエラー・定数定義src/pkg/syscall/zsysnum_freebsd_386.go
: FreeBSD/386アーキテクチャ向けシステムコール番号定義src/pkg/syscall/zsysnum_freebsd_amd64.go
: FreeBSD/amd64アーキテクチャ向けシステムコール番号定義src/pkg/syscall/zsysnum_freebsd_arm.go
: FreeBSD/armアーキテクチャ向けシステムコール番号定義
変更の概要:
-
src/pkg/syscall/mkerrors.sh
:includes_FreeBSD
変数に#include <sys/mman.h>
が追加されました。これにより、sys/mman.h
で定義されている定数(PROT_*
,MAP_*
など)が生成対象に含まれるようになります。
-
src/pkg/syscall/zerrors_freebsd_386.go
,src/pkg/syscall/zerrors_freebsd_amd64.go
,src/pkg/syscall/zerrors_freebsd_arm.go
:PROT_EXEC
,PROT_NONE
,PROT_READ
,PROT_WRITE
などのPROT_*
定数が追加されました。MAP_ANON
,MAP_ANONYMOUS
,MAP_COPY
,MAP_FILE
,MAP_FIXED
,MAP_HASSEMAPHORE
,MAP_NOCORE
,MAP_NORESERVE
,MAP_NOSYNC
,MAP_PREFAULT_READ
,MAP_PRIVATE
,MAP_RENAME
,MAP_RESERVED0080
,MAP_RESERVED0100
,MAP_SHARED
,MAP_STACK
などのMAP_*
定数が追加されました。- その他、FreeBSDのバージョンアップに伴う多数の新しい定数や既存定数の値の更新が行われました。例えば、
DLT_*
、IFF_*
、IPPROTO_*
、TCP_*
など、多岐にわたる定数が追加・更新されています。 ELAST
エラーコードの値が更新され、新しいエラーコードECAPMODE
が追加されました。
-
src/pkg/syscall/zsysnum_freebsd_386.go
,src/pkg/syscall/zsysnum_freebsd_amd64.go
,src/pkg/syscall/zsysnum_freebsd_arm.go
:- 新しいシステムコール番号(例:
SYS_CLOCK_GETCPUCLOCKID2
,SYS_WAIT6
)が追加されました。 SYS_CAP_NEW
システムコールの引数型がu_int64_t
からuint64_t
に変更されました。- ARMアーキテクチャ向けには、
SYS_CAP_RIGHTS_GET
,SYS_CAP_RIGHTS_LIMIT
,SYS_CAP_IOCTLS_LIMIT
,SYS_CAP_IOCTLS_GET
,SYS_CAP_FCNTLS_LIMIT
,SYS_CAP_FCNTLS_GET
などの新しいシステムコールが追加されています。
- 新しいシステムコール番号(例:
コアとなるコードの解説
src/pkg/syscall/mkerrors.sh
の変更
--- a/src/pkg/syscall/mkerrors.sh
+++ b/src/pkg/syscall/mkerrors.sh
@@ -43,6 +43,7 @@ includes_FreeBSD='\
#include <sys/socket.h>\
#include <sys/sockio.h>\
#include <sys/sysctl.h>\
+#include <sys/mman.h>\
#include <sys/wait.h>\
#include <sys/ioctl.h>\
#include <net/bpf.h>\
この変更は、mkerrors.sh
スクリプトがFreeBSDのシステムコール定数を生成する際に参照するCヘッダーファイルのリストに、<sys/mman.h>
を追加するものです。
mkerrors.sh
は、includes_FreeBSD
変数に定義されたCヘッダーファイルを読み込み、その中に定義されているマクロや定数をGoのコードに変換します。<sys/mman.h>
は、mmap(2)
やmprotect(2)
システムコールで使用されるPROT_*
やMAP_*
といったメモリマッピング関連の定数を定義しています。この行が追加されたことで、スクリプトが実行されるたびに、これらの重要な定数がGoのsyscall
パッケージに自動的に取り込まれるようになります。これにより、GoプログラムがFreeBSDのメモリ管理機能をより完全に利用できるようになります。
src/pkg/syscall/zerrors_freebsd_386.go
(amd64, armも同様) の変更
--- a/src/pkg/syscall/zerrors_freebsd_386.go
+++ b/src/pkg/syscall/zerrors_freebsd_386.go
@@ -92,6 +92,31 @@ const (
AF_VENDOR45 = 0x81
AF_VENDOR46 = 0x83
AF_VENDOR47 = 0x85
+ B0 = 0x0
+ B110 = 0x6e
+ B115200 = 0x1c200
+ B1200 = 0x4b0
+ B134 = 0x86
+ B14400 = 0x3840
+ B150 = 0x96
+ B1800 = 0x708
+ B19200 = 0x4b00
+ B200 = 0xc8
+ B230400 = 0x38400
+ B2400 = 0x960
+ B28800 = 0x7080
+ B300 = 0x12c
+ B38400 = 0x9600
+ B460800 = 0x70800
+ B4800 = 0x12c0
+ B50 = 0x32
+ B57600 = 0xe100
+ B600 = 0x258
+ B7200 = 0x1c20
+ B75 = 0x4b
+ B76800 = 0x12c00
+ B921600 = 0xe1000
+ B9600 = 0x2580
BIOCFEEDBACK = 0x8004427c
BIOCFLUSH = 0x20004268
BIOCGBLEN = 0x40044266
...
@@ -867,10 +973,44 @@ const (
IP_TOS = 0x3
IP_TTL = 0x4
IP_UNBLOCK_SOURCE = 0x49
+ ISIG = 0x80
+ ISTRIP = 0x20
+ IXANY = 0x800
+ IXOFF = 0x400
+ IXON = 0x200
LOCK_EX = 0x2
LOCK_NB = 0x4
LOCK_SH = 0x1
LOCK_UN = 0x8
+ MADV_AUTOSYNC = 0x7
+ MADV_CORE = 0x9
+ MADV_DONTNEED = 0x4
+ MADV_FREE = 0x5
+ MADV_NOCORE = 0x8
+ MADV_NORMAL = 0x0
+ MADV_NOSYNC = 0x6
+ MADV_PROTECT = 0xa
+ MADV_RANDOM = 0x1
+ MADV_SEQUENTIAL = 0x2
+ MADV_WILLNEED = 0x3
+ MAP_ANON = 0x1000
+ MAP_ANONYMOUS = 0x1000
+ MAP_COPY = 0x2
+ MAP_FILE = 0x0
+ MAP_FIXED = 0x10
+ MAP_HASSEMAPHORE = 0x200
+ MAP_NOCORE = 0x20000
+ MAP_NORESERVE = 0x40
+ MAP_NOSYNC = 0x800
+ MAP_PREFAULT_READ = 0x40000
+ MAP_PRIVATE = 0x2
+ MAP_RENAME = 0x20
+ MAP_RESERVED0080 = 0x80
+ MAP_RESERVED0100 = 0x100
+ MAP_SHARED = 0x1
+ MAP_STACK = 0x400
+ MCL_CURRENT = 0x1
+ MCL_FUTURE = 0x2
MSG_COMPAT = 0x8000
MSG_CTRUNC = 0x20
MSG_DONTROUTE = 0x4
...
@@ -933,6 +1084,14 @@ const (
O_TRUNC = 0x400
O_TTY_INIT = 0x80000
O_WRONLY = 0x1
+ PARENB = 0x1000
+ PARMRK = 0x8
+ PARODD = 0x2000
+ PENDIN = 0x20000000
+ PROT_EXEC = 0x4
+ PROT_NONE = 0x0
+ PROT_READ = 0x1
+ PROT_WRITE = 0x2
RLIMIT_AS = 0xa
RLIMIT_CORE = 0x4
RLIMIT_CPU = 0x0
これらの差分は、mkerrors.sh
スクリプトの実行によって再生成されたzerrors_freebsd_386.go
ファイル(amd64およびarm版も同様)の内容を示しています。
特に注目すべきは、MAP_*
定数とPROT_*
定数の追加です。
MAP_*
定数:MAP_ANON
,MAP_ANONYMOUS
,MAP_PRIVATE
,MAP_SHARED
などが追加されています。これらはmmap
システムコールでメモリ領域をマッピングする際の動作を指定するために不可欠なフラグです。例えば、MAP_ANON
はファイルではなく匿名メモリ領域を確保する場合に、MAP_SHARED
は複数のプロセス間でメモリを共有する場合にそれぞれ使用されます。PROT_*
定数:PROT_EXEC
,PROT_NONE
,PROT_READ
,PROT_WRITE
が追加されています。これらはmmap
やmprotect
システムコールでメモリ領域のアクセス権限を設定するために使用されます。例えば、PROT_READ | PROT_WRITE
は読み書き可能なメモリ領域を意味します。
これらの定数がGoのsyscall
パッケージに追加されたことで、GoプログラムはFreeBSD上でメモリマッピングやメモリ保護を必要とする低レベルな操作を、Goの型安全なインターフェースを通じて直接行えるようになります。これにより、Goでより高度なシステムプログラミングが可能になり、例えば、JITコンパイラの実装や、特定のメモリ領域のアクセス権限を動的に変更するようなアプリケーションの開発が容易になります。
src/pkg/syscall/zsysnum_freebsd_386.go
(amd64, armも同様) の変更
--- a/src/pkg/syscall/zsysnum_freebsd_386.go
+++ b/src/pkg/syscall/zsysnum_freebsd_386.go
@@ -149,6 +149,7 @@ const (
SYS_FFCLOCK_GETCOUNTER = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( \
SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( \
+ SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,\
SYS_NTP_GETTIME = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, \
SYS_RFORK = 251 // { int rfork(int flags); }
@@ -320,7 +321,7 @@ const (
SYS_JAIL_REMOVE = 508 // { int jail_remove(int jid); }
SYS_CLOSEFROM = 509 // { int closefrom(int lowfd); }
SYS_LPATHCONF = 513 // { int lpathconf(char *path, int name); }
- SYS_CAP_NEW = 514 // { int cap_new(int fd, u_int64_t rights); }
+ SYS_CAP_NEW = 514 // { int cap_new(int fd, uint64_t rights); }
SYS_CAP_GETRIGHTS = 515 // { int cap_getrights(int fd, \
SYS_CAP_ENTER = 516 // { int cap_enter(void); }
SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); }
@@ -337,4 +338,5 @@ const (
SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, \
SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, \
SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, \
+ SYS_WAIT6 = 532 // { int wait6(int idtype, int id, \
)
この差分は、FreeBSDのシステムコール番号定義ファイルであるzsysnum_freebsd_386.go
(amd64およびarm版も同様)の変更を示しています。
主な変更点は以下の通りです。
- 新しいシステムコールの追加:
SYS_CLOCK_GETCPUCLOCKID2
やSYS_WAIT6
といった新しいシステムコールが追加されています。これらはFreeBSDの新しいバージョンで導入された機能に対応するためのものです。 - 既存システムコールの引数型の変更:
SYS_CAP_NEW
システムコールの引数型がu_int64_t
からuint64_t
に変更されています。これは、C言語の型定義の変更や、Goの型システムとの整合性を保つための調整と考えられます。 - ARMアーキテクチャ固有の追加: ARM版の
zsysnum_freebsd_arm.go
では、SYS_CAP_RIGHTS_GET
、SYS_CAP_RIGHTS_LIMIT
など、FreeBSDのCapability Modeに関連するシステムコールが多数追加されています。これは、ARMアーキテクチャにおけるFreeBSDのCapability Modeのサポート強化を反映しています。
これらの変更は、Goのsyscall
パッケージがFreeBSDの最新のシステムコールインターフェースに追従し、GoプログラムがFreeBSDの新しい機能や改善されたAPIを利用できるようにするために重要です。
関連リンク
- Go Issue 4929: syscall: add PROT_, MAP_ constants to freebsd
- Go Change-Id: 7438053 (Gerrit Code Review)
参考にした情報源リンク
- FreeBSD
mmap(2)
man page: https://www.freebsd.org/cgi/man.cgi?query=mmap&sektion=2 - FreeBSD
mprotect(2)
man page: https://www.freebsd.org/cgi/man.cgi?query=mprotect&sektion=2 - Go
syscall
package documentation: https://pkg.go.dev/syscall - Go source code on GitHub: https://github.com/golang/go
- Dave Cheney's blog (general Go programming insights): https://dave.cheney.net/ (特定の記事を参照したわけではありませんが、Goコミュニティにおける彼の貢献を考慮して記載)
- FreeBSD Handbook (System Calls): https://docs.freebsd.org/en/books/handbook/kernel/#kernel-system-calls