# 機能設計書：llvm-dwarfutil

## 1. 機能概要

### 1.1 機能名
llvm-dwarfutil - DWARFデバッグ情報の操作ユーティリティ

### 1.2 機能説明
llvm-dwarfutilは、DWARFデバッグ情報をコピー・変換・最適化するツールです。デバッグ情報のガベージコレクション、ODR（One Definition Rule）重複排除、アクセラレータテーブルの構築、分離デバッグファイルの作成などの機能を提供します。

### 1.3 関連する画面/API
- CLI（コマンドラインインターフェース）
- 入力：オブジェクトファイル（ELF形式）
- 出力：処理済みオブジェクトファイル、分離デバッグファイル

---

## 2. 入出力設計

### 2.1 入力
| 項目 | 型 | 必須 | 説明 |
|------|-----|------|------|
| input file | ファイルパス | Yes | 入力オブジェクトファイル |
| output file | ファイルパス | Yes | 出力オブジェクトファイル |

### 2.2 出力
| 項目 | 型 | 説明 |
|------|-----|------|
| output file | ファイル | 処理済みオブジェクトファイル |
| .debug file | ファイル | 分離デバッグファイル（--separate-debug-file時） |
| exit code | 整数 | 0: 成功、1: エラー |

### 2.3 コマンドラインオプション
| オプション | 説明 |
|-----------|------|
| --garbage-collection | 到達不能なデバッグ情報を削除（デフォルト: 有効） |
| --no-garbage-collection | ガベージコレクションを無効化 |
| --odr-deduplication | ODR重複排除を実行（デフォルト: 有効） |
| --no-odr-deduplication | ODR重複排除を無効化 |
| --separate-debug-file | デバッグ情報を分離ファイルに出力 |
| --no-separate-debug-file | 分離ファイル出力を無効化 |
| --tombstone=<value> | トゥームストーン値の種類（bfd/maxpc/universal/exec） |
| --linker=<value> | リンカーの種類（classic/parallel） |
| --build-accelerator=<value> | アクセラレータテーブルの種類（none/DWARF） |
| --num-threads=<N> | 使用スレッド数（0: 全ハードウェアスレッド） |
| --verbose | 詳細メッセージを出力 |
| --verify | 出力を検証 |
| --help | ヘルプを表示 |
| --version | バージョンを表示 |

---

## 3. 処理フロー

### 3.1 基本フロー

```
[開始]
   │
   ▼
[コマンドライン引数解析]
   │
   ▼
[オプション検証・設定]
   │
   ▼
[ターゲット初期化]
   │
   ▼
[入力ファイル読み込み]
   │
   ▼
[処理分岐]
   │
   ├─► ガベージコレクション有効 or アクセラレータテーブル構築
   │         │
   │         ▼
   │    [デバッグ情報リンキング] ──► linkDebugInfo()
   │         │
   │         ▼
   │    [リンク済みデバッグ情報を保存]
   │
   ├─► 分離デバッグファイル生成のみ
   │         │
   │         ▼
   │    splitDebugIntoSeparateFile()
   │
   └─► コピーのみ
             │
             ▼
        saveCopyOfFile()
   │
   ▼
[パーミッション適用]
   │
   ▼
[検証（--verify時）]
   │
   ▼
[終了]
```

### 3.2 デバッグ情報リンキング処理

```
applyCLOptions()
   │
   ▼
[DoGarbageCollection or AccelTableKind != None]
   │
   ▼
linkDebugInfo()
   │
   ▼
[LinkedDebugInfoBitsに出力]
   │
   ▼
saveLinkedDebugInfo()
   │
   ├─► BuildSeparateDebugFile
   │         │
   │         ├─► saveSeparateLinkedDebugInfo()
   │         │
   │         └─► saveNonDebugInfo()
   │
   └─► 単一ファイル
             │
             ▼
        saveSingleLinkedDebugInfo()
```

### 3.3 分離デバッグファイル生成

```
splitDebugIntoSeparateFile()
   │
   ▼
saveSeparateDebugInfo()
   │
   ├─► OnlyKeepDebug = true
   │
   ├─► CRC32計算（raw_crc_ostream）
   │
   └─► 出力ファイル書き込み
   │
   ▼
saveNonDebugInfo()
   │
   ├─► StripDebug = true
   │
   ├─► AddGnuDebugLink = 分離ファイル名
   │
   └─► GnuDebugLinkCRC32 = CRC32値
```

---

## 4. データ構造

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

```cpp
struct Options {
    std::string InputFileName;
    std::string OutputFileName;
    bool BuildSeparateDebugFile;     // 分離デバッグファイル生成
    bool DoODRDeduplication;         // ODR重複排除（デフォルト: true）
    bool DoGarbageCollection;        // ガベージコレクション（デフォルト: true）
    bool Verbose;                    // 詳細出力
    bool Verify;                     // 出力検証
    unsigned NumThreads;             // スレッド数（0: 自動）
    TombstoneKind Tombstone;         // トゥームストーン種類
    bool UseDWARFLinkerParallel;     // パラレルリンカー使用
    DwarfUtilAccelKind AccelTableKind; // アクセラレータテーブル種類

    std::string getSeparateDebugFileName() const;  // .debugファイル名取得
};
```

### 4.2 トゥームストーン種類

```cpp
enum class TombstoneKind {
    BFD,       // BFDスタイル（GNU binutils互換）
    MaxPC,     // 最大PC値
    Universal, // 汎用
    Exec       // 実行可能
};
```

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

```cpp
enum class DwarfUtilAccelKind {
    None,   // 生成しない
    DWARF   // DWARF形式
};
```

### 4.4 CRC32計算ストリーム

```cpp
class raw_crc_ostream : public raw_ostream {
    raw_ostream &OS;
    uint32_t CRC32 = 0;

    void write_impl(const char *Ptr, size_t Size) override {
        CRC32 = crc32(CRC32, ArrayRef<uint8_t>(...));
        OS.write(Ptr, Size);
    }

    uint32_t getCRC32() { return CRC32; }
};
```

---

## 5. 主要機能

### 5.1 ガベージコレクション
- 到達不能なデバッグ情報を削除
- コード参照のないDIEを除去
- デフォルトで有効

### 5.2 ODR重複排除
- 同一の型定義を1つにマージ
- ガベージコレクションと組み合わせて使用
- デフォルトで有効

### 5.3 分離デバッグファイル
- デバッグ情報を別ファイル（.debug）に分離
- 元ファイルには.gnu_debuglinkセクションを追加
- CRC32で整合性を確保

### 5.4 出力検証
- 生成されたDWARF情報の整合性を検証
- DWARFContext::verify()を使用

---

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

### 6.1 エラーケース
| エラー | 原因 | 対応 |
|--------|------|------|
| 位置引数が2つでない | 入出力ファイル指定不足 | エラーメッセージ出力、終了 |
| 不明なオプション | 無効なコマンドラインオプション | エラーメッセージ出力、終了 |
| 不明なtombstone値 | 無効なトゥームストーン種類 | エラーメッセージ出力、終了 |
| 不明なlinker値 | 無効なリンカー種類 | エラーメッセージ出力、終了 |
| 不明なbuild-accelerator値 | 無効なアクセラレータ種類 | エラーメッセージ出力、終了 |
| ODRとGC同時無効化 | 非互換オプション | エラーメッセージ出力、終了 |
| 分離ファイル＋stdout | 非互換出力先 | エラーメッセージ出力、終了 |
| サポートされないファイル形式 | 非ELF形式 | エラーメッセージ出力、終了 |
| 検証失敗 | 出力DWARF不正 | エラーメッセージ出力、終了 |

### 6.2 警告
| 警告 | 状況 |
|------|------|
| --num-threadsが1に変更 | --verbose指定時 |
| 検証スキップ | stdout出力時 |

---

## 7. 技術仕様

### 7.1 サポートファイル形式
- ELF32LE（32ビットリトルエンディアン）
- ELF64LE（64ビットリトルエンディアン）
- ELF32BE（32ビットビッグエンディアン）
- ELF64BE（64ビットビッグエンディアン）

### 7.2 objcopy統合
```cpp
objcopy::ConfigManager Config;
Config.Common.OnlyKeepDebug = true;   // デバッグのみ保持
Config.Common.StripDebug = true;      // デバッグを削除
Config.Common.AddGnuDebugLink = ...;  // .gnu_debuglinkを追加
```

### 7.3 デバッグセクション判定
```cpp
bool isDebugSection(StringRef SecName) {
    // .debug_*、.zdebug_*などのセクションを判定
}
```

### 7.4 マルチスレッド処理
- `--num-threads=0`で全ハードウェアスレッドを使用
- `--verbose`指定時は自動的に1スレッドに制限

---

## 8. 制約事項

### 8.1 オプション制約
- `--odr-deduplication`は`--garbage-collection`と併用必須
- `--separate-debug-file`はstdout出力（`-`）と非互換
- `--verbose`指定時はマルチスレッド無効

### 8.2 入力制約
- ELF形式のオブジェクトファイルのみ対応
- 入力と出力の両方のファイルパス指定が必須

---

## 9. 非機能要件

### 9.1 パフォーマンス
- マルチスレッド処理による高速化
- パラレルリンカーオプション

### 9.2 互換性
- GNU binutilsのトゥームストーン形式に対応
- .gnu_debuglinkセクションで分離デバッグファイルをリンク

---

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

### 10.1 エントリーポイント
- **ファイル**: `llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp`
- **関数**: `main()` (475-548行目)

### 10.2 重要な関数
| 関数名 | 行番号 | 説明 |
|--------|--------|------|
| main() | 475-548 | エントリーポイント |
| validateAndSetOptions() | 70-165 | オプション検証・設定 |
| applyCLOptions() | 445-470 | メイン処理ロジック |
| linkDebugInfo() | (外部) | デバッグ情報リンキング |
| saveLinkedDebugInfo() | 409-428 | リンク済みデバッグ情報保存 |
| splitDebugIntoSeparateFile() | 299-311 | 分離デバッグファイル生成 |
| saveSeparateDebugInfo() | 252-274 | 分離デバッグ情報保存 |
| saveNonDebugInfo() | 276-297 | 非デバッグ情報保存 |
| verifyOutput() | 188-224 | 出力検証 |
| setConfigToAddNewDebugSections() | 167-186 | デバッグセクション追加設定 |
| addSectionsFromLinkedData() | 315-355 | リンクデータからセクション追加 |

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

```
main()
├── DwarfutilOptTable::ParseArgs()              [486行目]
├── validateAndSetOptions()                     [501行目]
│   ├── Args.hasFlag() (各オプション)           [91-98行目]
│   ├── Tombstone解析                           [105-119行目]
│   ├── Linker解析                              [121-131行目]
│   └── AccelTable解析                          [133-144行目]
├── InitializeAllTargets()                      [504行目]
├── MemoryBuffer::getFileOrSTDIN()              [510行目]
├── object::createBinary()                      [515行目]
├── FilePermissionsApplier::create()            [519行目]
├── applyCLOptions()                            [529行目]
│   ├── [GC or AccelTable]
│   │   ├── linkDebugInfo()                     [453行目]
│   │   └── saveLinkedDebugInfo()               [457行目]
│   │       ├── saveSeparateLinkedDebugInfo()   [413行目]
│   │       │   ├── addSectionsFromLinkedData() [369行目]
│   │       │   └── objcopy::executeObjcopyOnBinary() [376行目]
│   │       ├── saveNonDebugInfo()              [419行目]
│   │       └── saveSingleLinkedDebugInfo()     [422行目]
│   ├── [BuildSeparateDebugFile]
│   │   └── splitDebugIntoSeparateFile()        [462行目]
│   │       ├── saveSeparateDebugInfo()         [302行目]
│   │       │   └── raw_crc_ostream             [263行目]
│   │       └── saveNonDebugInfo()              [307行目]
│   └── [else]
│       └── saveCopyOfFile()                    [465行目]
├── PermsApplierOrErr->apply()                  [535行目]
└── verifyOutput()                              [543行目]
    └── DICtx->verify()                         [206行目]
```

### 10.4 データフロー図

```
入力ファイル (ELF)
         │
         ▼
    ┌─────────────────────┐
    │ MemoryBuffer読み込み │
    │ createBinary()      │
    └─────────────────────┘
         │
         ▼ ObjectFile
    ┌─────────────────────┐
    │ applyCLOptions()    │
    │ 処理分岐            │
    └─────────────────────┘
         │
         ├─► GC/AccelTable有効
         │        │
         │        ▼
         │   ┌─────────────────────┐
         │   │ linkDebugInfo()     │ ← デバッグ情報リンキング
         │   └─────────────────────┘
         │        │
         │        ▼ LinkedDebugInfoBits
         │   ┌─────────────────────┐
         │   │ addSectionsFromLinkedData │
         │   │ (ELF形式判定)       │
         │   └─────────────────────┘
         │        │
         │        ▼
         │   ┌─────────────────────┐
         │   │ objcopy::executeObjcopyOnBinary │
         │   └─────────────────────┘
         │
         ├─► --separate-debug-file
         │        │
         │        ▼
         │   ┌─────────────────────┐
         │   │ saveSeparateDebugInfo │
         │   │ (raw_crc_ostream)   │ ← CRC32計算
         │   └─────────────────────┘
         │        │
         │        ▼
         │   ┌─────────────────────┐
         │   │ saveNonDebugInfo    │
         │   │ AddGnuDebugLink     │
         │   └─────────────────────┘
         │
         └─► コピーのみ
                  │
                  ▼
             ┌─────────────────────┐
             │ saveCopyOfFile()    │
             └─────────────────────┘
         │
         ▼
    ┌─────────────────────┐
    │ verifyOutput()      │ ← --verify時
    │ DICtx->verify()     │
    └─────────────────────┘
         │
         ▼
      出力ファイル
      (+ .debugファイル)
```

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

| ファイルパス | 役割 |
|-------------|------|
| llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp | メインソースファイル（549行） |
| llvm/tools/llvm-dwarfutil/DebugInfoLinker.h | デバッグ情報リンカーインターフェース |
| llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | デバッグ情報リンカー実装 |
| llvm/tools/llvm-dwarfutil/Options.h | オプション構造体定義 |
| llvm/tools/llvm-dwarfutil/Options.td | オプション定義（TableGen） |
| llvm/tools/llvm-dwarfutil/Error.h | エラーハンドリング |
| llvm/include/llvm/ObjCopy/ObjCopy.h | objcopy API |
| llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h | DWARFコンテキスト |
| llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h | DWARF検証 |

---

## 11. 使用例

### 11.1 基本的な使用（GC＋ODR重複排除）
```bash
llvm-dwarfutil input.o output.o
```

### 11.2 分離デバッグファイルの生成
```bash
llvm-dwarfutil --separate-debug-file input.o output.o
# output.o と output.o.debug が生成される
```

### 11.3 GCのみ（ODR重複排除なし）
```bash
llvm-dwarfutil --no-odr-deduplication input.o output.o
```

### 11.4 単純なコピー（GCなし）
```bash
llvm-dwarfutil --no-garbage-collection input.o output.o
```

### 11.5 アクセラレータテーブルの構築
```bash
llvm-dwarfutil --build-accelerator=DWARF input.o output.o
```

### 11.6 パラレルリンカーを使用
```bash
llvm-dwarfutil --linker=parallel input.o output.o
```

### 11.7 出力の検証
```bash
llvm-dwarfutil --verify input.o output.o
```

### 11.8 詳細出力
```bash
llvm-dwarfutil --verbose input.o output.o
```

---

## 12. 改訂履歴

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