# 機能設計書 110-llvm-offload-binary

## 概要

本ドキュメントは、llvm-offload-binary機能の設計仕様を記述する。llvm-offload-binaryは、複数のデバイスオブジェクトファイルを単一のバイナリにバンドルしたり、バンドルから抽出したりするツールである。

### 本機能の処理概要

llvm-offload-binaryは、異なるGPUアーキテクチャ向けのデバイスオブジェクトファイルを単一のバイナリにパッケージングするユーティリティである。出力されたバイナリはホストセクションに埋め込むことで、オフロードコードを含むファットバイナリを作成できる。また、既存のオフロードバイナリからデバイスイメージを抽出する機能も提供する。

**業務上の目的・背景**：GPUオフロードプログラミング（CUDA、HIP、OpenMP等）では、複数のGPUアーキテクチャ向けのコードを単一の実行ファイルに含める必要がある。llvm-offload-binaryは、これらのデバイスコードをカスタムバイナリ形式でパッケージングし、ホスト実行ファイルに埋め込めるようにする。ビルドシステムやリンカラッパーと連携して使用される。

**機能の利用シーン**：ファットバイナリのビルド、マルチアーキテクチャサポートの実現、デバイスイメージの抽出・検査に使用される。

**主要な処理内容**：
1. バンドル作成（-o指定時）
   - 複数のデバイスイメージを読み込み
   - OffloadBinary形式でシリアライズ
   - 単一ファイルに出力
2. 抽出（入力ファイル指定時）
   - オフロードバイナリの解析
   - 条件に合致するイメージの抽出
   - ファイルまたはアーカイブとして出力

**関連システム・外部連携**：clang-offload-bundler、clang-linker-wrapper、ビルドシステムと連携する。

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

## 関連画面

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

## 機能種別

データ変換処理 / パッケージング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | ファイルパス | No | 抽出元ファイル | バンドル時は不要 |
| -o | 文字列 | No | 出力ファイル | 抽出時は不要 |
| --image | キー=値リスト | Yes | デバイスイメージ指定 | - |
| --archive | フラグ | No | アーカイブ形式で出力 | 抽出時のみ |

### --imageオプション形式

キー=値の形式で複数のパラメータを指定:

| キー | 説明 | 必須 |
|-----|------|------|
| file | デバイスオブジェクトファイルパス | Yes（バンドル時） |
| triple | ターゲットトリプル | Yes（バンドル時） |
| arch | アーキテクチャ | No |
| kind | オフロード種別（cuda/hip/openmp等） | No |

### 入力データソース

- デバイスオブジェクトファイル
- オフロードバイナリファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| オフロードバイナリ | バイナリ | バンドル時の出力 |
| デバイスイメージ | バイナリ | 抽出時の出力 |
| アーカイブ | .a形式 | --archive時の出力 |

### 出力先

指定された出力ファイル、または自動生成ファイル名

## 処理フロー

### 処理シーケンス

```
1. 初期化
   └─ 引数解析
2. モード判定
   ├─ OutputFile指定: バンドルモード
   └─ InputFile指定: 抽出モード
3. バンドル処理（bundleImages）
   └─ 各イメージをOffloadBinary形式でシリアライズ
4. 抽出処理（unbundleImages）
   └─ イメージを抽出してファイル/アーカイブに出力
5. 完了
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C{OutputFile && InputFile?}
    C -->|両方指定| D[エラー: 排他]
    C -->|OutputFile| E[bundleImages]
    C -->|InputFile| F[unbundleImages]
    C -->|どちらもなし| G[ヘルプ表示]
    E --> H[--imageごとにループ]
    H --> I[ファイル読み込み]
    I --> J[OffloadBinary::write]
    J --> K[writeFile]
    F --> L[ファイル読み込み]
    L --> M[extractOffloadBinaries]
    M --> N{--archive?}
    N -->|Yes| O[writeArchive]
    N -->|No| P[writeFile]
    K --> Q[終了]
    O --> Q
    P --> Q
    D --> R[エラー終了]
    G --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-110-1 | 排他処理 | -oと入力ファイルは排他的 | 常時 |
| BR-110-2 | file必須 | バンドル時は--imageにfile必須 | バンドル時 |
| BR-110-3 | イメージ種別自動判定 | ファイル拡張子とマジックナンバーから種別判定 | バンドル時 |
| BR-110-4 | アライメント | OffloadBinaryはアライメントを維持 | 常時 |

### 計算ロジック

イメージ種別の判定:
- identify_magic()でビットコードかを判定
- ファイル拡張子から種別を推定
- 明示的なkind指定があればそれを使用

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 排他エラー | -oと入力ファイル両方指定 | エラーメッセージ、終了 |
| - | file未指定 | バンドル時にfile引数なし | エラーメッセージ、終了 |
| - | ファイル読み込み失敗 | ファイルが存在しない | エラーメッセージ、終了 |
| - | アライメントエラー | バイナリのアライメント不正 | エラーメッセージ、終了 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

特に定義なし。

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

入力ファイルはOffloadBinary形式として検証される。

## 備考

clang-offload-packagerは非推奨。llvm-offload-binaryを使用すること。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OffloadBinary.h | `llvm/include/llvm/Object/OffloadBinary.h` | OffloadBinary、OffloadingImageクラス |

**読解のコツ**: OffloadBinaryがカスタムバイナリ形式を表現し、OffloadingImageがデバイスイメージとメタデータを保持することを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-offload-binary.cpp | `llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp` | main関数（218-258行目） |

**主要処理フロー**:
1. **219行目**: シグナルハンドラ登録
2. **220-225行目**: 引数解析
3. **227-230行目**: clang-offload-packager非推奨警告
4. **232-235行目**: ヘルプ表示
5. **237行目**: PackagerExecutable設定
6. **243-247行目**: 排他チェック
7. **249-254行目**: bundleImagesまたはunbundleImages呼び出し

#### Step 3: バンドル処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-offload-binary.cpp | `llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp` | bundleImages関数（87-136行目） |

**主要処理フロー**:
- **88-89行目**: 出力バッファ準備
- **90-129行目**: --imageごとにループ
- **93行目**: getImageArguments()で引数解析
- **95-97行目**: file必須チェック
- **100-116行目**: ファイル読み込みとイメージ種別判定
- **117-123行目**: メタデータ設定
- **124-128行目**: OffloadBinary::write()でシリアライズ
- **132-134行目**: writeFile()で出力

#### Step 4: 抽出処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | llvm-offload-binary.cpp | `llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp` | unbundleImages関数（138-216行目） |

**主要処理フロー**:
- **139-149行目**: ファイル読み込みとアライメント確認
- **151-153行目**: extractOffloadBinaries()で解析
- **156-178行目**: --imageごとにマッチするイメージを抽出
- **180-194行目**: --archive時はwriteArchive()
- **195-211行目**: 通常時はwriteFile()またはファイル名自動生成

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

```
main (218行目)
    │
    ├─ sys::PrintStackTraceOnErrorSignal (219行目)
    │
    ├─ ParseCommandLineOptions (221行目)
    │
    ├─ bundleImages (250行目) [-o指定時]
    │      ├─ DeviceImagesループ (90行目)
    │      │      ├─ getImageArguments (93行目)
    │      │      ├─ MemoryBuffer::getFileOrSTDIN (103行目)
    │      │      ├─ identify_magic (109行目)
    │      │      ├─ getImageKind (112-113行目)
    │      │      └─ OffloadBinary::write (124行目)
    │      └─ writeFile (132行目)
    │
    └─ unbundleImages (252行目) [入力ファイル指定時]
           ├─ MemoryBuffer::getFileOrSTDIN (139行目)
           ├─ extractOffloadBinaries (152行目)
           ├─ DeviceImagesループ (156行目)
           │      └─ マッチング処理 (165-172行目)
           ├─ writeArchive (191行目) [--archive時]
           └─ writeFile (200, 209行目) [通常時]
```

### データフロー図

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

デバイスオブジェクト ───▶ bundleImages ───▶ オフロードバイナリ
(--image file=...)        │
                          ├─ 種別判定（ビットコード/ELF等）
                          ├─ メタデータ付加
                          └─ OffloadBinary形式でシリアライズ

オフロードバイナリ ───▶ unbundleImages ───▶ デバイスイメージ
                          │                    (個別ファイル/アーカイブ)
                          ├─ extractOffloadBinaries
                          ├─ --imageでフィルタリング
                          └─ 出力形式選択
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-offload-binary.cpp | `llvm/tools/llvm-offload-binary/llvm-offload-binary.cpp` | ソース | メインエントリーポイント（259行） |
| CMakeLists.txt | `llvm/tools/llvm-offload-binary/CMakeLists.txt` | ビルド設定 | ビルド構成 |
| OffloadBinary.h | `llvm/include/llvm/Object/OffloadBinary.h` | ヘッダ | OffloadBinaryクラス |
| ArchiveWriter.h | `llvm/include/llvm/Object/ArchiveWriter.h` | ヘッダ | アーカイブ書き込みAPI |
