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

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

このコミットは、Go言語のツールチェインに含まれるaddr2lineコマンドとobjdumpコマンドにおける、Windowsの実行ファイル形式であるPE (Portable Executable) ファイルのテキストセクション開始アドレスの計算に関するバグ修正です。具体的には、PEファイルの.textセクションの仮想アドレスに、イメージベースアドレスを加算することで、正しい開始アドレスを導出するように変更されています。

コミット

commit 6c7bef551b32c2f7f2371b21cc8d51d807737ef3
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Thu May 15 12:44:29 2014 +1000

    cmd/addr2line, cmd/objdump: fix pe text section starting address
    
    fixes windows build
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/97500043

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

https://github.com/golang/go/commit/6c7bef551b32c2f7f2371b21cc8d51d807737ef3

元コミット内容

このコミットは、cmd/addr2linecmd/objdumpの2つのコマンドにおいて、PEファイルのテキストセクションの開始アドレスの計算方法を修正するものです。これにより、Windowsビルドが正しく動作するようになります。

変更の背景

Go言語のツールチェインには、デバッグやバイナリ解析に役立つユーティリティが含まれています。addr2lineは実行ファイル内のアドレスからソースコードの行番号を特定するツールであり、objdumpは実行ファイルのオブジェクトコードを逆アセンブルして表示するツールです。これらのツールがWindows上で生成されたPE形式の実行ファイルを正確に解析するためには、ファイル内の各セクション(特にコードが格納される.textセクション)のメモリ上の正確な開始アドレスを把握する必要があります。

以前の実装では、PEファイルの.textセクションの開始アドレスを計算する際に、セクションヘッダに記述されているVirtualAddressのみを使用していたと考えられます。しかし、PEファイルがメモリにロードされる際には、そのファイルがロードされるベースアドレス(ImageBase)が存在します。セクションのVirtualAddressは、このImageBaseからの相対オフセットとして解釈されるべきです。したがって、正しいメモリ上の開始アドレスを得るためには、ImageBaseVirtualAddressを合算する必要がありました。

この計算の誤りが、Windows環境でのビルドやデバッグツールの動作に問題を引き起こしていたため、この修正が必要となりました。コミットメッセージにある「fixes windows build」という記述は、この問題がWindows環境でのGoプログラムのビルドプロセスや、ビルドされたバイナリの解析に影響を与えていたことを示唆しています。

前提知識の解説

PE (Portable Executable) ファイル形式

PEは、Microsoft Windowsオペレーティングシステムで使用される実行可能ファイル、オブジェクトコード、DLL (Dynamic Link Library) などのファイル形式です。PEファイルは、DOSヘッダ、PEヘッダ(ファイルヘッダとオプションヘッダを含む)、セクションヘッダ、そして実際のセクションデータで構成されます。

  • DOSヘッダ: 互換性のために存在し、古いDOSシステムで実行された場合に「This program cannot be run in DOS mode.」のようなメッセージを表示します。
  • PEヘッダ:
    • ファイルヘッダ: マシンタイプ、セクションの数、タイムスタンプなどの基本的な情報を含みます。
    • オプションヘッダ: PEファイルの最も重要な部分の一つで、実行可能イメージのメモリレイアウトに関する情報を含みます。ここには、ImageBaseAddressOfEntryPointSectionAlignmentFileAlignmentなどのフィールドが含まれます。
      • ImageBase: 実行ファイルがメモリにロードされる推奨ベースアドレスです。DLLの場合、このアドレスはロード時に変更される可能性があります(リベース)。
  • セクションヘッダ: 各セクション(例: .text.data.rdata)に関する情報を含みます。
    • VirtualAddress: セクションがメモリにロードされた際の、ImageBaseからの相対アドレス(RVA: Relative Virtual Address)です。
    • VirtualSize: メモリ上でのセクションのサイズです。
    • PointerToRawData: ファイル内でのセクションデータのオフセットです。
    • SizeOfRawData: ファイル内でのセクションデータのサイズです。
  • セクションデータ: 実際のコード、初期化済みデータ、未初期化データなどが格納されます。.textセクションは通常、実行可能なコードを含みます。

addr2lineコマンド

addr2lineは、プログラムの実行中に発生したエラーのスタックトレースなどで表示されるメモリアドレスを、対応するソースファイル名と行番号に変換するために使用されるユーティリティです。デバッグ時に、クラッシュした場所や特定の関数が呼び出された場所を特定するのに非常に役立ちます。このツールは、実行ファイル内に含まれるデバッグ情報(DWARF形式など)を解析してアドレスとソースコードのマッピングを行います。

objdumpコマンド

objdumpは、オブジェクトファイルや実行ファイルの情報を表示するためのユーティリティです。これには、逆アセンブルされたコード、セクションヘッダ、シンボルテーブル、リロケーションエントリなどが含まれます。開発者がバイナリの内部構造を理解したり、最適化の効果を確認したりする際に利用されます。

技術的詳細

このコミットの技術的な核心は、PEファイルのメモリロードメカニズムの正確な理解と、それに基づくアドレス計算の修正です。

PEファイルがWindowsによってメモリにロードされる際、オペレーティングシステムはまず、PEヘッダのオプションヘッダに指定されたImageBaseアドレスにファイルをロードしようとします。このImageBaseは、実行ファイル全体がメモリ上で開始する仮想アドレスです。

各セクション(例: .text.data)は、そのセクションヘッダ内にVirtualAddressというフィールドを持っています。このVirtualAddressは、ImageBaseからの相対的なオフセット(RVA)として定義されています。つまり、セクションが実際にメモリにロードされる絶対アドレスは、ImageBase + VirtualAddressによって計算されます。

以前のaddr2lineobjdumpの実装では、.textセクションの開始アドレスをsect.VirtualAddressのみで取得していました。これは、ImageBaseが0であるか、あるいはVirtualAddressが既に絶対アドレスとして扱われるような特定の状況下では問題ないかもしれませんが、一般的なPEファイルの構造においては不正確です。特に、ImageBaseが非ゼロの値を持つ場合、この計算誤りにより、ツールが.textセクションのコードを誤ったメモリ位置にあると認識し、結果としてデバッグ情報の解析や逆アセンブルが失敗する原因となっていました。

この修正では、pe.NewFile(f)でPEファイルをパースした後、obj.OptionalHeaderからImageBaseを取得するロジックが追加されました。PEファイルには32ビット版と64ビット版があり、それぞれpe.OptionalHeader32pe.OptionalHeader64という異なる構造体でオプションヘッダが表現されます。このため、switch文を使って適切なヘッダタイプを判別し、そこからImageBaseフィールドを抽出しています。

最終的に、.textセクションのVirtualAddressにこの取得したImageBaseを加算することで、メモリ上の正しい絶対開始アドレスtextStartを計算しています。

// 修正前:
// textStart = uint64(sect.VirtualAddress)

// 修正後:
// var imageBase uint64
// switch oh := obj.OptionalHeader.(type) {
// case *pe.OptionalHeader32:
//     imageBase = uint64(oh.ImageBase)
// case *pe.OptionalHeader64:
//     imageBase = oh.ImageBase
// default:
//     return 0, nil, nil, fmt.Errorf("pe file format not recognized")
// }
// if sect := obj.Section(".text"); sect != nil {
//     textStart = imageBase + uint64(sect.VirtualAddress)
// }

この変更により、addr2lineobjdumpはWindowsのPEファイルをより正確に解析できるようになり、Windows環境でのGo言語開発におけるデバッグとバイナリ解析の信頼性が向上しました。

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

このコミットでは、src/cmd/addr2line/main.gosrc/cmd/objdump/main.goの2つのファイルが変更されています。両ファイルにおけるloadTables関数内で、PEファイルの.textセクションの開始アドレスを計算するロジックが修正されています。

src/cmd/addr2line/main.go の変更点

--- a/src/cmd/addr2line/main.go
+++ b/src/cmd/addr2line/main.go
@@ -138,8 +138,17 @@ func loadTables(f *os.File) (textStart uint64, symtab, pclntab []byte, err error)
 	}\n 
 	if obj, err := pe.NewFile(f); err == nil {
+		var imageBase uint64
+		switch oh := obj.OptionalHeader.(type) {
+		case *pe.OptionalHeader32:
+			imageBase = uint64(oh.ImageBase)
+		case *pe.OptionalHeader64:
+			imageBase = oh.ImageBase
+		default:
+			return 0, nil, nil, fmt.Errorf("pe file format not recognized")
+		}
 		if sect := obj.Section(".text"); sect != nil {
-			textStart = uint64(sect.VirtualAddress)
+			textStart = imageBase + uint64(sect.VirtualAddress)
 		}
 		if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {
 			return 0, nil, nil, err

src/cmd/objdump/main.go の変更点

--- a/src/cmd/objdump/main.go
+++ b/src/cmd/objdump/main.go
@@ -318,8 +318,17 @@ func loadTables(f *os.File) (textStart uint64, textData, symtab, pclntab []byte,
 	}\n 
 	if obj, err := pe.NewFile(f); err == nil {
+		var imageBase uint64
+		switch oh := obj.OptionalHeader.(type) {
+		case *pe.OptionalHeader32:
+			imageBase = uint64(oh.ImageBase)
+		case *pe.OptionalHeader64:
+			imageBase = oh.ImageBase
+		default:
+			return 0, nil, nil, nil, fmt.Errorf("pe file format not recognized")
+		}
 		if sect := obj.Section(".text"); sect != nil {
-			textStart = uint64(sect.VirtualAddress)
+			textStart = imageBase + uint64(sect.VirtualAddress)
 			textData, _ = sect.Data()
 		}
 		if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {

コアとなるコードの解説

両方のファイルで、loadTables関数は実行ファイルからシンボルテーブルやPCLNテーブル(Goのプロファイリング情報)などのデバッグ関連情報をロードする役割を担っています。この関数内で、PEファイルが検出された場合に以下の変更が加えられました。

  1. imageBase変数の導入: uint64型のimageBase変数が新しく宣言されました。この変数は、PEファイルがメモリにロードされる際のベースアドレスを保持します。

  2. オプションヘッダの型判定とImageBaseの取得: obj.OptionalHeaderはインターフェース型であり、実際の型はPEファイルのビット数(32ビットまたは64ビット)によって異なります。

    • switch oh := obj.OptionalHeader.(type)構文を使用して、obj.OptionalHeaderの具体的な型を判定しています。
    • case *pe.OptionalHeader32:: オプションヘッダが32ビット版の場合、oh.ImageBaseuint64にキャストしてimageBaseに代入します。
    • case *pe.OptionalHeader64:: オプションヘッダが64ビット版の場合、oh.ImageBaseを直接imageBaseに代入します。
    • default:: 認識できないPEファイル形式の場合、エラーを返します。これは、将来的に新しいPEヘッダのバリアントが登場した場合に備えた堅牢なエラーハンドリングです。
  3. .textセクション開始アドレスの修正計算:

    • 以前は、.textセクションのVirtualAddressを直接textStartとして使用していました。
    • 修正後は、textStart = imageBase + uint64(sect.VirtualAddress)という計算式に変更されました。これにより、セクションの仮想アドレスがImageBaseからの相対オフセットとして正しく解釈され、メモリ上の絶対アドレスがtextStartに設定されるようになりました。

この変更により、addr2lineobjdumpは、WindowsのPE実行ファイルにおいて、コードセクションの正確なメモリ開始アドレスを特定できるようになり、デバッグ情報のマッピングや逆アセンブルが正しく行われるようになりました。

関連リンク

  • Go言語のdebug/peパッケージのドキュメント: https://pkg.go.dev/debug/pe
  • Microsoft Portable Executable and Common Object File Format Specification: (公式ドキュメントへの直接リンクは変動する可能性があるため、検索エンジンで「Microsoft Portable Executable and Common Object File Format Specification」と検索することを推奨します。)

参考にした情報源リンク

  • PEファイル形式に関する一般的な情報源(例: Wikipedia, Microsoft Learnドキュメント)
  • Go言語のdebug/peパッケージのソースコード
  • addr2lineおよびobjdumpコマンドの一般的な動作に関する情報# [インデックス 19360] ファイルの概要

このコミットは、Go言語のツールチェインに含まれるaddr2lineコマンドとobjdumpコマンドにおける、Windowsの実行ファイル形式であるPE (Portable Executable) ファイルのテキストセクション開始アドレスの計算に関するバグ修正です。具体的には、PEファイルの.textセクションの仮想アドレスに、イメージベースアドレスを加算することで、正しい開始アドレスを導出するように変更されています。

コミット

commit 6c7bef551b32c2f7f2371b21cc8d51d807737ef3
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Thu May 15 12:44:29 2014 +1000

    cmd/addr2line, cmd/objdump: fix pe text section starting address
    
    fixes windows build
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/97500043

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

https://github.com/golang/go/commit/6c7bef551b32c2f7f2371b21cc8d51d807737ef3

元コミット内容

このコミットは、cmd/addr2linecmd/objdumpの2つのコマンドにおいて、PEファイルのテキストセクションの開始アドレスの計算方法を修正するものです。これにより、Windowsビルドが正しく動作するようになります。

変更の背景

Go言語のツールチェインには、デバッグやバイナリ解析に役立つユーティリティが含まれています。addr2lineは実行ファイル内のアドレスからソースコードの行番号を特定するツールであり、objdumpは実行ファイルのオブジェクトコードを逆アセンブルして表示するツールです。これらのツールがWindows上で生成されたPE形式の実行ファイルを正確に解析するためには、ファイル内の各セクション(特にコードが格納される.textセクション)のメモリ上の正確な開始アドレスを把握する必要があります。

以前の実装では、PEファイルの.textセクションの開始アドレスを計算する際に、セクションヘッダに記述されているVirtualAddressのみを使用していたと考えられます。しかし、PEファイルがメモリにロードされる際には、そのファイルがロードされるベースアドレス(ImageBase)が存在します。セクションのVirtualAddressは、このImageBaseからの相対オフセットとして解釈されるべきです。したがって、正しいメモリ上の開始アドレスを得るためには、ImageBaseVirtualAddressを合算する必要がありました。

この計算の誤りが、Windows環境でのビルドやデバッグツールの動作に問題を引き起こしていたため、この修正が必要となりました。コミットメッセージにある「fixes windows build」という記述は、この問題がWindows環境でのGoプログラムのビルドプロセスや、ビルドされたバイナリの解析に影響を与えていたことを示唆しています。

前提知識の解説

PE (Portable Executable) ファイル形式

PEは、Microsoft Windowsオペレーティングシステムで使用される実行可能ファイル、オブジェクトコード、DLL (Dynamic Link Library) などのファイル形式です。PEファイルは、DOSヘッダ、PEヘッダ(ファイルヘッダとオプションヘッダを含む)、セクションヘッダ、そして実際のセクションデータで構成されます。

  • DOSヘッダ: 互換性のために存在し、古いDOSシステムで実行された場合に「This program cannot be run in DOS mode.」のようなメッセージを表示します。
  • PEヘッダ:
    • ファイルヘッダ: マシンタイプ、セクションの数、タイムスタンプなどの基本的な情報を含みます。
    • オプションヘッダ: PEファイルの最も重要な部分の一つで、実行可能イメージのメモリレイアウトに関する情報を含みます。ここには、ImageBaseAddressOfEntryPointSectionAlignmentFileAlignmentなどのフィールドが含まれます。
      • ImageBase: 実行ファイルがメモリにロードされる推奨ベースアドレスです。DLLの場合、このアドレスはロード時に変更される可能性があります(リベース)。
  • セクションヘッダ: 各セクション(例: .text.data.rdata)に関する情報を含みます。
    • VirtualAddress: セクションがメモリにロードされた際の、ImageBaseからの相対アドレス(RVA: Relative Virtual Address)です。
    • VirtualSize: メモリ上でのセクションのサイズです。
    • PointerToRawData: ファイル内でのセクションデータのオフセットです。
    • SizeOfRawData: ファイル内でのセクションデータのサイズです。
  • セクションデータ: 実際のコード、初期化済みデータ、未初期化データなどが格納されます。.textセクションは通常、実行可能なコードを含みます。

addr2lineコマンド

addr2lineは、プログラムの実行中に発生したエラーのスタックトレースなどで表示されるメモリアドレスを、対応するソースファイル名と行番号に変換するために使用されるユーティリティです。デバッグ時に、クラッシュした場所や特定の関数が呼び出された場所を特定するのに非常に役立ちます。このツールは、実行ファイル内に含まれるデバッグ情報(DWARF形式など)を解析してアドレスとソースコードのマッピングを行います。

objdumpコマンド

objdumpは、オブジェクトファイルや実行ファイルの情報を表示するためのユーティリティです。これには、逆アセンブルされたコード、セクションヘッダ、シンボルテーブル、リロケーションエントリなどが含まれます。開発者がバイナリの内部構造を理解したり、最適化の効果を確認したりする際に利用されます。

技術的詳細

このコミットの技術的な核心は、PEファイルのメモリロードメカニズムの正確な理解と、それに基づくアドレス計算の修正です。

PEファイルがWindowsによってメモリにロードされる際、オペレーティングシステムはまず、PEヘッダのオプションヘッダに指定されたImageBaseアドレスにファイルをロードしようとします。このImageBaseは、実行ファイル全体がメモリ上で開始する仮想アドレスです。

各セクション(例: .text.data)は、そのセクションヘッダ内にVirtualAddressというフィールドを持っています。このVirtualAddressは、ImageBaseからの相対的なオフセット(RVA)として定義されています。つまり、セクションが実際にメモリにロードされる絶対アドレスは、ImageBase + VirtualAddressによって計算されます。

以前のaddr2lineobjdumpの実装では、.textセクションの開始アドレスをsect.VirtualAddressのみで取得していました。これは、ImageBaseが0であるか、あるいはVirtualAddressが既に絶対アドレスとして扱われるような特定の状況下では問題ないかもしれませんが、一般的なPEファイルの構造においては不正確です。特に、ImageBaseが非ゼロの値を持つ場合、この計算誤りにより、ツールが.textセクションのコードを誤ったメモリ位置にあると認識し、結果としてデバッグ情報の解析や逆アセンブルが失敗する原因となっていました。

この修正では、pe.NewFile(f)でPEファイルをパースした後、obj.OptionalHeaderからImageBaseを取得するロジックが追加されました。PEファイルには32ビット版と64ビット版があり、それぞれpe.OptionalHeader32pe.OptionalHeader64という異なる構造体でオプションヘッダが表現されます。このため、switch文を使って適切なヘッダタイプを判別し、そこからImageBaseフィールドを抽出しています。

最終的に、.textセクションのVirtualAddressにこの取得したImageBaseを加算することで、メモリ上の正しい絶対開始アドレスtextStartを計算しています。

// 修正前:
// textStart = uint64(sect.VirtualAddress)

// 修正後:
// var imageBase uint64
// switch oh := obj.OptionalHeader.(type) {
// case *pe.OptionalHeader32:
//     imageBase = uint64(oh.ImageBase)
// case *pe.OptionalHeader64:
//     imageBase = oh.ImageBase
// default:
//     return 0, nil, nil, fmt.Errorf("pe file format not recognized")
// }
// if sect := obj.Section(".text"); sect != nil {
//     textStart = imageBase + uint64(sect.VirtualAddress)
// }

この変更により、addr2lineobjdumpはWindowsのPEファイルをより正確に解析できるようになり、Windows環境でのGo言語開発におけるデバッグとバイナリ解析の信頼性が向上しました。

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

このコミットでは、src/cmd/addr2line/main.gosrc/cmd/objdump/main.goの2つのファイルが変更されています。両ファイルにおけるloadTables関数内で、PEファイルの.textセクションの開始アドレスを計算するロジックが修正されています。

src/cmd/addr2line/main.go の変更点

--- a/src/cmd/addr2line/main.go
+++ b/src/cmd/addr2line/main.go
@@ -138,8 +138,17 @@ func loadTables(f *os.File) (textStart uint64, symtab, pclntab []byte, err error)
 	}\n 
 	if obj, err := pe.NewFile(f); err == nil {
+		var imageBase uint64
+		switch oh := obj.OptionalHeader.(type) {
+		case *pe.OptionalHeader32:
+			imageBase = uint64(oh.ImageBase)
+		case *pe.OptionalHeader64:
+			imageBase = oh.ImageBase
+		default:
+			return 0, nil, nil, fmt.Errorf("pe file format not recognized")
+		}
 		if sect := obj.Section(".text"); sect != nil {
-			textStart = uint64(sect.VirtualAddress)
+			textStart = imageBase + uint64(sect.VirtualAddress)
 		}
 		if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {
 			return 0, nil, nil, err

src/cmd/objdump/main.go の変更点

--- a/src/cmd/objdump/main.go
+++ b/src/cmd/objdump/main.go
@@ -318,8 +318,17 @@ func loadTables(f *os.File) (textStart uint64, textData, symtab, pclntab []byte,
 	}\n 
 	if obj, err := pe.NewFile(f); err == nil {
+		var imageBase uint64
+		switch oh := obj.OptionalHeader.(type) {
+		case *pe.OptionalHeader32:
+			imageBase = uint64(oh.ImageBase)
+		case *pe.OptionalHeader64:
+			imageBase = oh.ImageBase
+		default:
+			return 0, nil, nil, nil, fmt.Errorf("pe file format not recognized")
+		}
 		if sect := obj.Section(".text"); sect != nil {
-			textStart = uint64(sect.VirtualAddress)
+			textStart = imageBase + uint64(sect.VirtualAddress)
 			textData, _ = sect.Data()
 		}
 		if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {

コアとなるコードの解説

両方のファイルで、loadTables関数は実行ファイルからシンボルテーブルやPCLNテーブル(Goのプロファイリング情報)などのデバッグ関連情報をロードする役割を担っています。この関数内で、PEファイルが検出された場合に以下の変更が加えられました。

  1. imageBase変数の導入: uint64型のimageBase変数が新しく宣言されました。この変数は、PEファイルがメモリにロードされる際のベースアドレスを保持します。

  2. オプションヘッダの型判定とImageBaseの取得: obj.OptionalHeaderはインターフェース型であり、実際の型はPEファイルのビット数(32ビットまたは64ビット)によって異なります。

    • switch oh := obj.OptionalHeader.(type)構文を使用して、obj.OptionalHeaderの具体的な型を判定しています。
    • case *pe.OptionalHeader32:: オプションヘッダが32ビット版の場合、oh.ImageBaseuint64にキャストしてimageBaseに代入します。
    • case *pe.OptionalHeader64:: オプションヘッダが64ビット版の場合、oh.ImageBaseを直接imageBaseに代入します。
    • default:: 認識できないPEファイル形式の場合、エラーを返します。これは、将来的に新しいPEヘッダのバリアントが登場した場合に備えた堅牢なエラーハンドリングです。
  3. .textセクション開始アドレスの修正計算:

    • 以前は、.textセクションのVirtualAddressを直接textStartとして使用していました。
    • 修正後は、textStart = imageBase + uint64(sect.VirtualAddress)という計算式に変更されました。これにより、セクションの仮想アドレスがImageBaseからの相対オフセットとして正しく解釈され、メモリ上の絶対アドレスがtextStartに設定されるようになりました。

この変更により、addr2lineobjdumpは、WindowsのPE実行ファイルにおいて、コードセクションの正確なメモリ開始アドレスを特定できるようになり、デバッグ情報のマッピングや逆アセンブルが正しく行われるようになりました。

関連リンク

  • Go言語のdebug/peパッケージのドキュメント: https://pkg.go.dev/debug/pe
  • Microsoft Portable Executable and Common Object File Format Specification: (公式ドキュメントへの直接リンクは変動する可能性があるため、検索エンジンで「Microsoft Portable Executable and Common Object File Format Specification」と検索することを推奨します。)

参考にした情報源リンク

  • PEファイル形式に関する一般的な情報源(例: Wikipedia, Microsoft Learnドキュメント)
  • Go言語のdebug/peパッケージのソースコード
  • addr2lineおよびobjdumpコマンドの一般的な動作に関する情報