# 機能設計書 105-llvm-modextract

## 概要

本ドキュメントは、llvm-modextract機能の設計仕様を記述する。llvm-modextractは、マルチモジュールビットコードファイルから特定のモジュールを抽出するツールである。

### 本機能の処理概要

llvm-modextractは、複数のモジュールを含むLLVMビットコードファイルから、インデックスで指定された単一のモジュールを抽出し、新しいビットコードファイルとして出力するユーティリティである。LTO（Link Time Optimization）などで使用されるマルチモジュール形式のテストや検証に使用される。

**業務上の目的・背景**：LTOビルドでは、複数のオブジェクトファイルが単一のビットコードファイルにまとめられることがある。このようなマルチモジュールファイルの個別モジュールを検査・テストする際に、特定のモジュールだけを抽出する必要がある。llvm-modextractはこの目的を達成するための専用ツールである。

**機能の利用シーン**：LTOビルドのデバッグ、マルチモジュールビットコード機能のテスト、特定モジュールの単独解析に使用される。

**主要な処理内容**：
1. マルチモジュールビットコードファイルの読み込み
2. モジュールリストの取得
3. 指定インデックスのモジュール抽出
4. バイナリ抽出またはパース抽出の選択
5. 抽出したモジュールのビットコード出力

**関連システム・外部連携**：LLVMビットコードライブラリ、LTOツールチェーンと連携する。

**権限による制御**：特になし。ファイルシステムへの読み書き権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIインターフェース | 主画面 | コマンドライン実行 |

## 機能種別

データ変換処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | ファイルパス | Yes | マルチモジュールビットコードファイル | 有効なビットコード |
| -o | 文字列 | Yes | 出力ファイル名 | - |
| -n | 整数 | Yes | 抽出するモジュールのインデックス（0始まり） | 0以上、モジュール数未満 |
| -b | フラグ | No | バイナリ抽出モード | - |

### 入力データソース

- マルチモジュールビットコードファイル
- 標準入力（-指定時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ビットコード | バイナリ | 抽出されたモジュールのビットコード |

### 出力先

指定された出力ファイル（-oオプション）

## 処理フロー

### 処理シーケンス

```
1. 引数解析
   └─ 入力ファイル、出力ファイル、インデックス、モードの解析
2. ファイル読み込み
   └─ MemoryBuffer::getFileOrSTDINで入力読み込み
3. モジュールリスト取得
   └─ getBitcodeModuleListでモジュール一覧取得
4. インデックス検証
   └─ 指定インデックスが範囲内か確認
5. 抽出処理
   ├─ バイナリモード: 生データを直接コピー
   └─ 通常モード: モジュールをパースしてシリアライズ
6. 出力
   └─ ビットコードを出力ファイルに書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C[入力ファイル読み込み]
    C --> D[getBitcodeModuleList]
    D --> E{インデックス検証}
    E -->|範囲外| F[エラー終了]
    E -->|範囲内| G{バイナリモード?}
    G -->|Yes| H[バイナリデータコピー]
    G -->|No| I[モジュールパース]
    H --> J[copyStrtab]
    I --> K[WriteBitcodeToFile]
    J --> L[出力ファイル書き込み]
    K --> L
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-105-1 | インデックス範囲チェック | 指定インデックスはモジュール数未満であること | 常時 |
| BR-105-2 | バイナリ抽出 | -bオプション時は生データをコピー | -b指定時 |
| BR-105-3 | パース抽出 | 通常時はモジュールをパースして再シリアライズ | -b未指定時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

データベースは使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | インデックス範囲外 | -nがモジュール数以上 | エラーメッセージ出力、終了 |
| - | ファイル読み込み失敗 | 入力ファイルが無効 | エラーメッセージ出力、終了 |
| - | 出力失敗 | 出力ファイルに書き込めない | エラーメッセージ出力、終了 |

### リトライ仕様

なし

## トランザクション仕様

該当なし

## パフォーマンス要件

特に定義なし。

## セキュリティ考慮事項

入力ファイルはLLVMビットコード形式として検証される。

## 備考

主にテスト目的で使用されるツール。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BitcodeReader.h | `llvm/include/llvm/Bitcode/BitcodeReader.h` | getBitcodeModuleList、BitcodeModuleクラス |
| 1-2 | BitcodeWriter.h | `llvm/include/llvm/Bitcode/BitcodeWriter.h` | WriteBitcodeToFile、BitcodeWriterクラス |

**読解のコツ**: BitcodeModuleがマルチモジュールファイル内の個別モジュールを表現し、getBuffer()で生データ、parseModule()でパース済みモジュールを取得できることを理解する。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-modextract.cpp | `llvm/tools/llvm-modextract/llvm-modextract.cpp` | 全体構造（87行と短い） |

**主要処理フロー**:
1. **26-45行目**: コマンドラインオプション定義（-b、-o、input、-n）
2. **47-49行目**: main関数開始、ParseCommandLineOptions
3. **53-54行目**: MemoryBuffer::getFileOrSTDINで入力読み込み
4. **55行目**: getBitcodeModuleListでモジュールリスト取得
5. **58-63行目**: インデックス範囲チェック
6. **65-68行目**: 出力ファイルオープン
7. **70-79行目**: バイナリモードの処理
8. **81-82行目**: 通常モードの処理（parseModule + WriteBitcodeToFile）
9. **84-85行目**: ファイル保持

#### Step 3: 抽出処理の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-modextract.cpp | `llvm/tools/llvm-modextract/llvm-modextract.cpp` | 70-82行目の抽出ロジック |

**主要処理フロー**:
- **70行目**: BinaryExtract条件分岐
- **71行目**: SmallVector<char, 0>で結果バッファ作成
- **72行目**: BitcodeWriterインスタンス作成
- **73-74行目**: Ms[ModuleIndex].getBuffer()で生データ取得、Resultにappend
- **75行目**: Writer.copyStrtab()で文字列テーブルコピー
- **76-78行目**: 結果を出力ファイルに書き込み、keep()で保持
- **81行目**: Ms[ModuleIndex].parseModule()でモジュールパース
- **82行目**: WriteBitcodeToFile()でビットコード出力

### プログラム呼び出し階層図

```
main (47行目)
    │
    ├─ cl::ParseCommandLineOptions (49行目)
    │
    ├─ MemoryBuffer::getFileOrSTDIN (53-54行目)
    │
    ├─ getBitcodeModuleList (55行目)
    │      └─ BitcodeModule のリスト取得
    │
    ├─ ToolOutputFile (66-67行目)
    │
    └─ 抽出処理
           │
           ├─ バイナリモード (-b)
           │      ├─ BitcodeWriter
           │      ├─ Ms[n].getBuffer()
           │      ├─ Result.append()
           │      └─ Writer.copyStrtab()
           │
           └─ 通常モード
                  ├─ Ms[n].parseModule()
                  └─ WriteBitcodeToFile()
```

### データフロー図

```
[入力]                    [処理]                    [出力]

マルチモジュール  ───▶  llvm-modextract  ───▶  単一モジュール
ビットコード           │                        ビットコード
(.bc)                  │
                       ├─ getBitcodeModuleList
                       │      └─ モジュール一覧取得
                       │
                       └─ 抽出処理
                              ├─ バイナリ: getBuffer()
                              └─ パース: parseModule()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-modextract.cpp | `llvm/tools/llvm-modextract/llvm-modextract.cpp` | ソース | メインエントリーポイント（87行） |
| CMakeLists.txt | `llvm/tools/llvm-modextract/CMakeLists.txt` | ビルド設定 | ビルド構成 |
| BitcodeReader.h | `llvm/include/llvm/Bitcode/BitcodeReader.h` | ヘッダ | ビットコード読み込みAPI |
| BitcodeWriter.h | `llvm/include/llvm/Bitcode/BitcodeWriter.h` | ヘッダ | ビットコード書き込みAPI |
