# 機能設計書：dsymutil

## 1. 機能概要

### 1.1 機能名
dsymutil - macOS用デバッグシンボルユーティリティ

### 1.2 機能説明
dsymutilは、macOS向けのdSYMバンドルを作成・更新するツールです。Darwin（macOS）標準のdsymutilのドロップイン置換を目指しており、実行ファイルのシンボルテーブルに含まれるデバッグシンボル情報を使用して、オブジェクトファイル内のDWARFデバッグ情報をリンクします。

### 1.3 関連する画面/API
- CLI（コマンドラインインターフェース）
- 入力：Mach-O実行ファイル/dSYMバンドル
- 出力：dSYMバンドル/フラットDWARFファイル

---

## 2. 入出力設計

### 2.1 入力
| 項目 | 型 | 必須 | 説明 |
|------|-----|------|------|
| input files | ファイルパス群 | Yes | Mach-O実行ファイルまたはdSYMバンドル |
| -o | ファイルパス | No | 出力ファイル/バンドル名 |
| --arch | アーキテクチャ | No | 処理対象アーキテクチャ（複数指定可） |

### 2.2 出力
| 項目 | 型 | 説明 |
|------|-----|------|
| dSYM bundle | ディレクトリ | dSYMバンドル（デフォルト） |
| DWARF file | ファイル | フラットDWARFファイル（--flat時） |
| exit code | 整数 | 0: 成功、1: エラー |

### 2.3 コマンドラインオプション
| オプション | 説明 |
|-----------|------|
| -o | 出力ファイル/バンドル名を指定 |
| --arch | 処理対象アーキテクチャを指定 |
| -f, --flat | dSYMバンドルではなくフラットファイルを出力 |
| -u, --update | 既存のdSYMを更新 |
| --no-output | 出力を生成しない |
| --no-odr | ODR重複排除を無効化 |
| --verify | 出力のDWARFを検証 |
| --verify-dwarf=<value> | DWARF検証の種類（none/input/output/all/auto） |
| --verbose | 詳細出力 |
| --quiet | 警告を抑制 |
| --statistics | 統計情報を出力 |
| -j, --threads=<N> | スレッド数を指定（0: 全スレッド） |
| --accelerator=<type> | アクセラレータテーブルの種類（Apple/Dwarf/Pub/Default/None） |
| --linker=<type> | DWARFリンカーの種類（classic/parallel） |
| --oso-prepend-path | OSOファイルのパスプレフィックス |
| --object-prefix-map | オブジェクトパスマッピング |
| --toolchain | ツールチェーン識別子 |
| --symbol-map | シンボルマップパス |
| --dump-debug-map | デバッグマップをダンプ |
| --symtab | シンボルテーブルをダンプ |
| --fat64 | 64ビットユニバーサルヘッダを強制 |
| --gen-reproducer | リプロデューサを生成 |
| --use-reproducer | リプロデューサを使用 |
| --remarks-prepend-path | リマークファイルパスプレフィックス |
| --remarks-output-format | リマーク出力形式 |
| --dsym-search-path | dSYM検索パス |
| --yaml-input | YAML形式のデバッグマップを入力として使用 |
| --help | ヘルプを表示 |
| --version | バージョンを表示 |

---

## 3. 処理フロー

### 3.1 基本フロー

```
[開始]
   │
   ▼
[コマンドライン引数解析]
   │
   ▼
[オプション検証]
   │
   ▼
[ターゲット初期化]
   │
   ▼
[Reproducerセットアップ]
   │
   ▼
[各入力ファイルを処理]
   │
   ├─► --symtab ──► dumpStab()
   │
   └─► 通常処理
         │
         ▼
   [デバッグマップ解析]
         │
         ▼
   [出力ファイル名決定]
         │
         ▼
   [各アーキテクチャをリンク]
         │
         ▼
   [ユニバーサルバイナリ生成（必要時）]
   │
   ▼
[終了]
```

### 3.2 dSYMバンドル生成フロー

```
getOutputFileName()
   │
   ▼
[出力モード判定]
   │
   ├─► stdout ("-") ──► OutputLocation("-")
   │
   ├─► --update ──► OutputLocation(InputFile)
   │
   ├─► --flat ──► OutputLocation(InputFile + ".dwarf")
   │
   └─► バンドル生成
         │
         ▼
   createBundleDir()
   │   │
   │   ▼
   │   [Contents/Resources/DWARF/ 作成]
   │
   └─► createPlistFile()
         │
         ▼
   [Info.plist 作成]
```

### 3.3 リンク処理フロー

```
[各デバッグマップに対して]
   │
   ▼
[一時ファイル作成（必要時）]
   │
   ▼
[DwarfLinkerForBinary作成]
   │
   ▼
[Linker.link(*Map)]
   │
   ▼
[出力検証（--verify時）]
   │
   ▼
[ユニバーサルバイナリ生成（複数アーキテクチャ時）]
```

---

## 4. データ構造

### 4.1 オプション構造体

```cpp
struct DsymutilOptions {
    bool DumpDebugMap = false;           // デバッグマップをダンプ
    bool DumpStab = false;               // シンボルテーブルをダンプ
    bool Flat = false;                   // フラットファイル出力
    bool InputIsYAMLDebugMap = false;    // YAML入力
    bool ForceKeepFunctionForStatic = false;
    bool NoObjectTimestamp = false;      // オブジェクトタイムスタンプ無視
    std::string OutputFile;              // 出力ファイル
    std::string Toolchain;               // ツールチェーン
    std::string ReproducerPath;          // リプロデューサパス
    std::vector<std::string> Archs;      // 対象アーキテクチャ
    std::vector<std::string> InputFiles; // 入力ファイル
    unsigned NumThreads;                 // スレッド数
    DWARFVerify Verify;                  // 検証モード
    ReproducerMode ReproMode;            // リプロデューサモード
    dsymutil::LinkOptions LinkOpts;      // リンクオプション
};
```

### 4.2 DWARF検証モード

```cpp
enum class DWARFVerify : uint8_t {
    None = 0,                    // 検証なし
    Input = 1 << 0,              // 入力を検証
    Output = 1 << 1,             // 出力を検証
    OutputOnValidInput = 1 << 2, // 入力が有効な場合のみ出力を検証
    All = Input | Output,        // すべて検証
    Auto = Input | OutputOnValidInput, // 自動
    Default = ...                // ビルド構成に依存
};
```

### 4.3 リプロデューサモード

```cpp
enum class ReproducerMode {
    GenerateOnExit,    // 終了時に生成
    GenerateOnCrash,   // クラッシュ時に生成
    Off,               // 無効
    Use                // 既存のリプロデューサを使用
};
```

### 4.4 アクセラレータテーブルの種類

```cpp
enum class DsymutilAccelTableKind {
    Apple,     // Apple形式
    Dwarf,     // DWARF形式
    Pub,       // Pub形式
    Default,   // デフォルト
    None       // 生成しない
};
```

### 4.5 出力位置

```cpp
struct OutputLocation {
    std::string DWARFFile;                    // DWARFファイルパス
    std::optional<std::string> ResourceDir;  // リソースディレクトリ
};
```

---

## 5. 主要機能

### 5.1 dSYMバンドル生成
- macOS標準のdSYMバンドル構造を生成
- Info.plistを自動生成
- CFBundleInfo情報を抽出して設定

### 5.2 ユニバーサルバイナリ対応
- 複数アーキテクチャのサポート
- Fat64ヘッダの自動/手動切り替え
- 4GB境界超過時の警告

### 5.3 DWARF検証
- 入力/出力のDWARF整合性を検証
- DWARF v5まで対応（v6以上は警告）

### 5.4 リプロデューサ
- クラッシュ時/終了時にリプロデューサを生成
- 既存のリプロデューサを使用してデバッグ可能

---

## 6. エラーハンドリング

### 6.1 エラーケース
| エラー | 原因 | 対応 |
|--------|------|------|
| 入力ファイルなし | ファイル指定なし | エラーメッセージ出力、終了 |
| --quietと--verbose同時指定 | 非互換オプション | エラーメッセージ出力、終了 |
| --flatなしでstdout出力 | 非互換出力 | エラーメッセージ出力、終了 |
| --flatで複数入力と-o同時指定 | 非互換オプション | エラーメッセージ出力、終了 |
| --gen-reproducerと--use-reproducer同時指定 | 非互換オプション | エラーメッセージ出力、終了 |
| 無効なアーキテクチャ | サポート外アーキテクチャ | エラーメッセージ出力、終了 |
| デバッグマップ解析失敗 | 不正な入力ファイル | エラーメッセージ出力、終了 |
| 出力検証失敗 | 不正なDWARF | エラーメッセージ出力、終了 |

### 6.2 警告
| 警告 | 状況 |
|------|------|
| 検証スキップ | stdout出力時、--no-output時、DWARF v6以上時 |
| デバッグシンボルなし | 実行ファイルにデバッグシンボルがない場合 |
| 4GB境界超過 | ユニバーサルバイナリのスライスが4GB境界を超える場合 |
| 不明なオプション | サポートされていないオプション |

---

## 7. 技術仕様

### 7.1 dSYMバンドル構造
```
<bundle name>.dSYM/
    Contents/
        Info.plist
        Resources/
            DWARF/
                <DWARF file(s)>
```

### 7.2 Info.plist生成
- CFBundleIdentifier、CFBundleVersion等を自動設定
- ツールチェーン情報を含めることが可能

### 7.3 マルチスレッド処理
- `--threads=0`で全ハードウェアスレッドを使用
- `--verbose`または`--dump-debug-map`時は1スレッドに制限
- `--statistics`時はアーキテクチャ間を順次処理

### 7.4 クラッシュリカバリ
```cpp
CrashRecoveryContext::Enable();
CrashRecoveryContext CRC;
CRC.DumpStackAndCleanupOnFailure = true;
const bool Crashed = !CRC.RunSafely([&]() { ... });
if (Crashed)
    (*Repro)->generate();
```

---

## 8. 制約事項

### 8.1 オプション制約
- `--quiet`と`--verbose`は同時指定不可
- `--flat`なしでstdout出力不可
- 複数入力で`--flat`と`-o`同時指定不可
- `--gen-reproducer`と`--use-reproducer`同時指定不可

### 8.2 プラットフォーム
- 主にmacOS向け（Mach-O形式）
- dSYMバンドルはmacOS固有

### 8.3 DWARF検証
- DWARF v5まで対応
- DWARF v6以上は検証スキップ

---

## 9. 非機能要件

### 9.1 パフォーマンス
- マルチスレッドリンキング
- スレッドプールによる並列処理

### 9.2 信頼性
- クラッシュリカバリコンテキスト
- リプロデューサによるデバッグ支援

### 9.3 互換性
- Darwin dsymutilのドロップイン置換
- ユニバーサルバイナリ対応

---

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

### 10.1 エントリーポイント
- **ファイル**: `llvm/tools/dsymutil/dsymutil.cpp`
- **関数**: `dsymutil_main()` (612-890行目)

### 10.2 重要な関数
| 関数名 | 行番号 | 説明 |
|--------|--------|------|
| dsymutil_main() | 612-890 | エントリーポイント |
| getOptions() | 291-408 | オプション解析 |
| getInputs() | 129-171 | 入力ファイル取得 |
| verifyOptions() | 174-204 | オプション検証 |
| getOutputFileName() | 561-610 | 出力ファイル名決定 |
| createBundleDir() | 476-485 | バンドルディレクトリ作成 |
| createPlistFile() | 410-474 | Info.plist作成 |
| verifyOutput() | 487-547 | 出力検証 |
| getAccelTableKind() | 206-226 | アクセラレータ種別取得 |
| getDWARFLinkerType() | 228-244 | リンカー種別取得 |
| getVerifyKind() | 266-287 | 検証種別取得 |
| getReproducerMode() | 246-264 | リプロデューサモード取得 |

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

```
dsymutil_main()
├── DsymutilOptTable::ParseArgs()               [618行目]
├── getOptions()                                [645行目]
│   ├── getVerifyKind()                         [300行目]
│   ├── getReproducerMode()                     [325行目]
│   ├── getAccelTableKind()                     [332行目]
│   ├── getDWARFLinkerType()                    [338行目]
│   ├── getInputs()                             [345行目]
│   └── verifyOptions()                         [405行目]
├── InitializeAllTargets()                      [653-656行目]
├── Reproducer::createReproducer()              [658行目]
├── [各入力ファイル処理]                         [674-887行目]
│   ├── dumpStab()                              [683行目]
│   ├── parseDebugMap()                         [691行目]
│   ├── getOutputFileName()                     [721行目]
│   │   ├── createBundleDir()                   [600行目]
│   │   └── createPlistFile()                   [602行目]
│   ├── [スレッドプール作成]                     [732-740行目]
│   ├── [CrashRecoveryContext設定]              [753-756行目]
│   ├── [各デバッグマップをリンク]               [758-830行目]
│   │   ├── DwarfLinkerForBinary()              [810行目]
│   │   ├── Linker.link(*Map)                   [812行目]
│   │   └── verifyOutput()                      [817行目]
│   └── MachOUtils::generateUniversalBinary()   [882行目]
└── [終了処理]
```

### 10.4 データフロー図

```
入力ファイル (Mach-O / dSYM)
         │
         ▼
    ┌─────────────────────┐
    │ getInputs()         │ ← dSYMバンドル展開
    └─────────────────────┘
         │
         ▼
    ┌─────────────────────┐
    │ parseDebugMap()     │ ← デバッグマップ解析
    │ BinaryHolder        │
    └─────────────────────┘
         │
         ▼ DebugMap[]
    ┌─────────────────────┐
    │ getOutputFileName() │
    │ ├─ createBundleDir  │
    │ └─ createPlistFile  │
    └─────────────────────┘
         │
         ▼
    ┌─────────────────────┐
    │ ThreadPool          │ ← 並列処理
    └─────────────────────┘
         │
         ▼ [各アーキテクチャ]
    ┌─────────────────────┐
    │ DwarfLinkerForBinary│
    │ Linker.link(*Map)   │
    └─────────────────────┘
         │
         ▼ 一時ファイル
    ┌─────────────────────┐
    │ verifyOutput()      │ ← --verify時
    │ DICtx->verify()     │
    └─────────────────────┘
         │
         ▼
    ┌─────────────────────┐
    │ generateUniversalBinary │ ← 複数アーキテクチャ時
    └─────────────────────┘
         │
         ▼
      dSYMバンドル / DWARFファイル
```

### 10.5 関連ファイル一覧

| ファイルパス | 役割 |
|-------------|------|
| llvm/tools/dsymutil/dsymutil.cpp | メインソースファイル（891行） |
| llvm/tools/dsymutil/dsymutil.h | ヘッダーファイル |
| llvm/tools/dsymutil/Options.td | オプション定義（TableGen） |
| llvm/tools/dsymutil/BinaryHolder.h | バイナリホルダー |
| llvm/tools/dsymutil/DebugMap.h | デバッグマップ |
| llvm/tools/dsymutil/DwarfLinkerForBinary.h | DWARFリンカー |
| llvm/tools/dsymutil/MachOUtils.h | Mach-Oユーティリティ |
| llvm/tools/dsymutil/LinkUtils.h | リンクユーティリティ |
| llvm/tools/dsymutil/CFBundle.h | CFBundleユーティリティ |
| llvm/tools/dsymutil/Reproducer.h | リプロデューサ |

---

## 11. 使用例

### 11.1 基本的な使用
```bash
dsymutil executable
# executable.dSYM が生成される
```

### 11.2 出力ファイル指定
```bash
dsymutil -o output.dSYM executable
```

### 11.3 フラットファイル出力
```bash
dsymutil --flat executable
# executable.dwarf が生成される
```

### 11.4 特定アーキテクチャのみ処理
```bash
dsymutil --arch=x86_64 executable
```

### 11.5 複数アーキテクチャを処理
```bash
dsymutil --arch=x86_64 --arch=arm64 executable
```

### 11.6 既存dSYMを更新
```bash
dsymutil --update existing.dSYM
```

### 11.7 DWARF検証を実行
```bash
dsymutil --verify executable
```

### 11.8 詳細出力
```bash
dsymutil --verbose executable
```

### 11.9 統計情報を出力
```bash
dsymutil --statistics executable
```

### 11.10 デバッグマップをダンプ
```bash
dsymutil --dump-debug-map executable
```

### 11.11 パラレルリンカーを使用
```bash
dsymutil --linker=parallel executable
```

### 11.12 アクセラレータテーブル種類を指定
```bash
dsymutil --accelerator=Apple executable
```

---

## 12. 改訂履歴

| 版数 | 日付 | 変更内容 | 担当者 |
|------|------|----------|--------|
| 1.0 | 2026-02-01 | 初版作成 | dsymutil機能設計書生成 |
