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

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

このコミットは、Go言語のsyscallパッケージにおけるlinux/armアーキテクチャ向けのZファイル(zerrors_linux_arm.goztypes_linux_arm.go)の再生成に関するものです。これらのファイルは、Linuxカーネルのシステムコールに関連する定数、エラーコード、データ構造をGo言語から利用できるように自動生成されたものです。

コミット

commit d2933e99021f9d1048cc25e0d0b0724f5bfc6ed6
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Tue Dec 20 07:42:00 2011 +0900

    syscall: regenerate z-files for linux/arm
    
    R=golang-dev, dave, rsc
    CC=golang-dev
    https://golang.org/cl/5496062

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

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

元コミット内容

このコミットの目的は、syscallパッケージ内のlinux/armアーキテクチャに特化したzerrors_linux_arm.goztypes_linux_arm.goファイルを再生成することです。これにより、Go言語がLinux ARM環境の最新のシステムコール定義と同期されることを意図しています。

変更の背景

Go言語のsyscallパッケージは、オペレーティングシステム(OS)の低レベルな機能、特にシステムコールへのアクセスを提供します。異なるOSやアーキテクチャ(例: Linux/ARM)では、システムコールの番号、引数、関連する定数やデータ構造が異なります。これらの差異をGo言語から透過的に扱うために、GoプロジェクトではC言語のヘッダーファイルからGoのコードを自動生成する仕組みが用いられています。

このコミットが行われた2011年12月時点では、Go言語はまだ比較的新しい言語であり、様々なプラットフォームへの対応が活発に進められていました。特にARMアーキテクチャは、組み込みシステムやモバイルデバイスで広く利用されており、Goがこれらの分野で普及するためには、正確で最新のシステムコール定義への対応が不可欠でした。

この「z-files」の再生成は、以下のいずれかの理由で行われたと考えられます。

  1. Linuxカーネルの更新: Linuxカーネルのバージョンアップに伴い、ARMアーキテクチャ向けのシステムコール定義、定数、またはデータ構造に変更があったため。
  2. Goのツールチェインの改善: godefscgoといったGoの内部ツールが改善され、より正確または効率的なコード生成が可能になったため。特に、生成ツールの変更(godefsからcgo -godefsへ)が示唆されています。
  3. ARM ABIの変更: ARMアーキテクチャのアプリケーションバイナリインターフェース(ABI)に微細な変更があり、それがシステムコールインターフェースに影響を与えたため。
  4. 既存の生成コードの不正確さの修正: 以前に生成されたコードに誤りや不足があり、それを修正するために再生成が必要になったため。

これらの背景により、GoのsyscallパッケージがLinux ARM環境で正しく機能し、最新のOSインターフェースと互換性を持つようにするために、Zファイルの再生成が実施されました。

前提知識の解説

このコミットを理解するためには、以下の概念が重要です。

  1. システムコール (System Call):

    • オペレーティングシステムが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。ファイルI/O、メモリ管理、プロセス制御、ネットワーク通信など、OSの核となる機能にアクセスするために使用されます。
    • Go言語のsyscallパッケージは、これらの低レベルなOS機能への直接的なアクセスを提供します。
  2. Go言語のsyscallパッケージ:

    • GoプログラムからOS固有のシステムコールを呼び出すための機能を提供します。
    • OSやアーキテクチャごとに異なるシステムコールの定義(定数、構造体など)を扱うため、Goのソースコードには各プラットフォームに特化したファイルが含まれています。
  3. Zファイル (Z-files):

    • Go言語のsyscallパッケージ内で、特定のOSおよびアーキテクチャ向けのシステムコール関連の定数やデータ構造が自動生成されたファイルを指す通称です。ファイル名がzで始まることが多い(例: zerrors_linux_arm.go, ztypes_linux_arm.go)。
    • これらのファイルは、C言語のヘッダーファイルからGoのコードを生成するツール(godefscgo)によって作成されます。手動で編集することは推奨されず、変更があった場合はツールで再生成されます。
  4. godefscgo -godefs:

    • godefsは、C言語の構造体や定数をGoの構造体や定数に変換するためのGoツールです。Goの初期のバージョンでは、CのヘッダーファイルからGoの型定義を生成するために独立して使用されることがありました。
    • cgoは、GoプログラムからC言語のコードを呼び出すためのGoの機能です。cgo -godefsは、cgoのサブコマンドの一つで、Cの定義からGoの定義を生成する機能を提供します。このコミットでは、生成メカニズムがgodefsからcgo -godefsに移行したことが示唆されています。これは、GoのビルドシステムとC言語の定義の統合がより密接になったことを意味します。
  5. ARMアーキテクチャ (ARM Architecture):

    • Advanced RISC Machineの略で、低消費電力と高性能を両立するRISC(Reduced Instruction Set Computer)ベースのプロセッサアーキテクチャです。
    • スマートフォン、タブレット、組み込みシステム、IoTデバイス、最近ではサーバーやデスクトップPCなど、幅広い分野で利用されています。
    • LinuxはARMプロセッサ上で広く動作しており、GoがARMデバイスをサポートするためには、ARM固有のシステムコールインターフェースへの正確な対応が不可欠です。
  6. ABI (Application Binary Interface):

    • アプリケーションとOS、またはアプリケーションとライブラリの間で、バイナリレベルでの互換性を定義するものです。これには、関数呼び出し規約、データ型のメモリレイアウト、レジスタの使用方法などが含まれます。
    • ABIの変更は、システムコールインターフェースに影響を与え、Zファイルの再生成が必要になることがあります。

技術的詳細

このコミットの技術的な核心は、GoのsyscallパッケージがLinux ARM環境のシステムコール定義をどのように取り込み、Goのコードとして表現するかという点にあります。

変更された2つのファイル、zerrors_linux_arm.goztypes_linux_arm.goは、それぞれ以下の役割を担っています。

  • zerrors_linux_arm.go: Linux ARM環境におけるシステムコール関連の定数(例: AF_UNSPEC, BPF_ADD, O_RDONLYなど)やエラーコード(例: EL2HLT)を定義します。これらの定数は、C言語のヘッダーファイル(例: /usr/include/linux/errno.h, /usr/include/asm-generic/socket.hなど)で定義されている値に対応します。
  • ztypes_linux_arm.go: Linux ARM環境におけるシステムコールで使用されるデータ構造(例: Timespec, Timeval, Stat_t, Direntなど)をGoの構造体として定義します。これらの構造体は、C言語の構造体(例: struct stat, struct dirent)のメモリレイアウトと厳密に一致するように生成されます。

コミットの差分から読み取れる主要な技術的変更点は以下の通りです。

  1. 生成ツールの変更:

    • zerrors_linux_arm.goのヘッダーコメントが// godefs -c gcc -gsyscall _const.cから// Created by cgo -godefs - DO NOT EDITおよび// cgo -godefs -- _const.goに変更されています。
    • ztypes_linux_arm.goも同様に// godefs -gsyscall types_linux.cから// Created by cgo -godefs - DO NOT EDITおよび// cgo -godefs types_linux.goに変更されています。
    • これは、Goのシステムコール定義の生成プロセスが、従来のgodefsコマンド単体、または特定のgodefsの呼び出し方から、cgo -godefsというより統合されたツールチェインに移行したことを明確に示しています。cgo -godefsは、C言語の定義をGoの型に変換する際に、cgoの持つCコンパイラとの連携能力をより活用できるようになったことを意味します。これにより、Cのヘッダーファイルのパースや、Goの型へのマッピングがより堅牢になった可能性があります。
  2. 定数表現の統一:

    • 多くの定数で、値が0から0x0へと変更されています。これは機能的な変更ではなく、単に数値リテラルの表現を16進数に統一したものです。自動生成ツールが16進数表記を好むようになった結果と考えられます。
  3. 定数の追加と移動:

    • zerrors_linux_arm.goでは、EL2HLT, EL2NSYNC, EL3HLT, EL3RSTといったエラーコードが、ファイルの先頭のconstブロックから、Errno型の定義の下に移動し、Errno(...)として再定義されています。これは、エラーコードの分類や表現方法がより厳密になったことを示唆しています。
    • また、LOCK_EX, LOCK_NB, LOCK_SH, LOCK_UN (ファイルロック関連)、RLIMIT_AS, RLIMIT_COREなどのRLIMIT定数(リソース制限関連)、RUSAGE_CHILDREN, RUSAGE_SELF, RUSAGE_THREAD(リソース使用量関連)など、新しい定数が多数追加されています。これは、GoのsyscallパッケージがサポートするLinuxシステムコールの範囲が拡張されたか、または以前は欠落していた重要な定数が追加されたことを意味します。
  4. 構造体のパディングとフィールドの変更:

    • ztypes_linux_arm.goでは、Timex, Stat_t, Statfs_t, Dirent, Cmsghdr, SockFprog, InotifyEvent, Termiosなどの構造体で、内部のパディングフィールドの名前がPad_godefs_XからPad_cgo_Xに変更されています。これは、生成ツールがcgoベースになったことによる命名規則の変更です。
    • Statfs_t構造体では、Fsid [8]byte /* __fsid_t */Fsid Fsidに変更され、新たにFsid構造体が定義されています。これは、C言語の__fsid_t型がGoでより適切な構造体としてマッピングされるようになったことを示します。
    • Cmsghdr構造体にはX__cmsg_data [0]byteフィールドが追加されています。これは、C言語の可変長配列(flexible array member)のGoでの表現に対応するため、または特定のABI要件を満たすための変更である可能性があります。
    • InotifyEvent構造体にはName [0]byteフィールドが追加されています。これも同様に、C言語のinotify_event構造体が持つ可変長の名前フィールドをGoで表現するための変更です。
    • これらの構造体の変更は、Linuxカーネルのヘッダーファイルにおける対応するC構造体の定義が更新されたか、またはcgo -godefsがCの構造体をGoにマッピングする際のロジックが改善された結果です。特に、パディングの変更やフィールドの追加は、異なるコンパイラやアーキテクチャでのメモリレイアウトの差異を吸収し、GoとCの間で正確なデータ交換を保証するために重要です。

これらの変更は、GoのsyscallパッケージがLinux ARM環境でより正確かつ堅牢に動作するための基盤を強化するものです。

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

このコミットで変更されたコアとなるコードは以下の2つのファイルです。

  1. src/pkg/syscall/zerrors_linux_arm.go:

    • ファイルのヘッダーコメントが変更され、生成元がcgo -godefsであることが明記されました。
    • 多数の定数(例: AF_UNSPEC, ARPHRD_NETROM, BPF_ADDなど)の値が0から0x0に変更されました。
    • EL2HLT, EL2NSYNC, EL3HLT, EL3RSTなどのエラーコードが、Errno型の一部として再定義されました。
    • LOCK_EX, LOCK_NB, LOCK_SH, LOCK_UN, RLIMIT_ASからRLIM_INFINITYまでのRLIMIT関連定数、RUSAGE_CHILDRENからRUSAGE_THREADまでのRUSAGE関連定数など、新しい定数が追加されました。
  2. src/pkg/syscall/ztypes_linux_arm.go:

    • ファイルのヘッダーコメントが変更され、生成元がcgo -godefsであることが明記されました。
    • Timespec, Timeval, Timex, Rlimit, Stat_t, Statfs_t, Dirent, RawSockaddrInet4, RawSockaddrInet6, RawSockaddrUnix, RawSockaddrLinklayer, RawSockaddrNetlink, Linger, IPMreq, IPMreqn, IPv6Mreq, Msghdr, Cmsghdr, Inet4Pktinfo, Inet6Pktinfo, Ucred, NlMsghdr, NlMsgerr, RtGenmsg, NlAttr, RtAttr, IfInfomsg, IfAddrmsg, RtMsg, RtNexthop, SockFilter, SockFprog, InotifyEvent, PtraceRegs, EpollEvent, Termiosといった構造体の定義が変更されました。
      • 特に、構造体内のパディングフィールドの名前がPad_godefs_XからPad_cgo_Xに変更されました。
      • Statfs_t構造体内のFsidフィールドが[8]byteから新しく定義されたFsid構造体型に変更されました。
      • Cmsghdr構造体とInotifyEvent構造体に[0]byteの可変長配列を示すフィールドが追加されました。
    • 以前はファイル先頭の単一のconstブロックにまとめられていた多数の定数(例: SizeofSockaddrInet4, IFA_UNSPEC, RT_SCOPE_UNIVERSE, VINTR, B0, TCGETSなど)が、関連する構造体や機能ごとに複数のconstブロックに分割・整理されました。

コアとなるコードの解説

これらの変更は、GoのsyscallパッケージがLinux ARM環境のシステムコールインターフェースとより正確に連携するためのものです。

  • zerrors_linux_arm.goの変更:

    • 定数の0から0x0への変更は、純粋にスタイル上のものです。Goのコンパイラにとってはどちらも同じ整数値として扱われますが、16進数表記に統一することで、生成されたコードの可読性や一貫性が向上します。
    • エラーコードの再分類と新しい定数の追加は、Linuxカーネルの進化や、Goがサポートするシステムコールの範囲の拡大に対応したものです。これにより、GoプログラムはLinux ARM環境でより多くのシステムコール機能にアクセスできるようになり、エラーハンドリングもより詳細に行えるようになります。
  • ztypes_linux_arm.goの変更:

    • 最も重要な変更は、生成ツールの変更(godefsからcgo -godefsへ)と、それに伴う構造体の定義の調整です。C言語の構造体とGo言語の構造体は、メモリ上でのレイアウトが厳密に一致している必要があります。これは、システムコールがC言語の構造体ポインタを引数として受け取るため、Goから渡される構造体がCの期待する形式と異なる場合、予期せぬ動作やクラッシュを引き起こす可能性があるためです。
    • パディングフィールドの名前変更(Pad_godefs_XからPad_cgo_X)は、生成ツールの変更を反映したものであり、Goの構造体がCの構造体とバイトアラインメント(メモリ配置)を正確に一致させるために必要な「詰め物」の役割を果たします。
    • Fsid構造体の導入や、CmsghdrInotifyEventにおける[0]byteフィールドの追加は、C言語の複雑な型(例: 可変長配列を持つ構造体)をGoで正確に表現するための改善です。これにより、Goのsyscallパッケージは、より複雑なLinuxシステムコールインターフェースにも対応できるようになります。
    • 定数の分割と整理は、コードのモジュール性、可読性、および保守性を向上させます。関連する定数がまとまることで、開発者が特定のシステムコールや機能に関連する定数を見つけやすくなります。

これらの変更は、GoのsyscallパッケージがLinux ARM環境で安定して動作し、最新のOS機能にアクセスできることを保証するための、低レベルながらも非常に重要な更新です。

関連リンク

参考にした情報源リンク

  • Goの公式リポジトリのコミット履歴
  • Goのsyscallパッケージのソースコード
  • Linuxカーネルのドキュメント(システムコール、ヘッダーファイルに関する一般的な知識)
  • cgoおよびgodefsツールの機能に関するGoのドキュメントやブログ記事
  • ARMアーキテクチャのABIに関する一般的な情報