# 機能設計書 62-llvm-pdbutil

## 概要

本ドキュメントは、LLVM llvm-pdbutil ツールの機能設計について記載する。llvm-pdbutilは、Windows PDB（Program Database）ファイルのダンプ、解析、操作を行う多機能ユーティリティである。

### 本機能の処理概要

llvm-pdbutilは、MicrosoftのPDBフォーマットで記録されたデバッグ情報を解析・操作するためのツールである。PDBファイルの内容をダンプ、YAML形式への変換、複数PDBのマージ、特定オフセットの意味の説明など、多彩な機能を提供する。

**業務上の目的・背景**：Windows環境でのデバッグやプログラム解析において、PDBファイルは実行ファイルのシンボル情報・型情報・行番号情報を格納する重要なファイルである。llvm-pdbutilは、PDBファイルの内容を人間が読める形式で表示したり、テスト用のPDBファイルを生成したりするために使用される。LLVMデバッガ(LLDB)やリンカ(LLD)の開発・テストにも活用される。

**機能の利用シーン**：
- PDBファイルの内容調査・デバッグ情報の確認
- コンパイラやリンカの出力検証
- PDBファイルの構造理解・学習
- テスト用のPDBファイル生成（YAML to PDB変換）
- 複数のPDBファイルの型情報マージ

**主要な処理内容**：
1. dumpサブコマンド：MSFコンテナとCodeViewデバッグ情報のダンプ
2. bytesサブコマンド：PDBファイルのバイナリデータ表示
3. prettyサブコマンド：型・シンボル情報のセマンティックな表示
4. yaml2pdbサブコマンド：YAMLからPDBファイルを生成
5. pdb2yamlサブコマンド：PDBファイルをYAML形式で出力
6. mergeサブコマンド：複数PDBの型情報をマージ
7. explainサブコマンド：ファイルオフセットの意味を説明
8. exportサブコマンド：ストリームをバイナリファイルとして出力

**関連システム・外部連携**：LLVM PDBライブラリ、MSFライブラリ、CodeViewライブラリ

**権限による制御**：特になし（ファイルシステムへのアクセス権限のみ必要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIツール | 主機能 | コマンドラインインターフェースによる操作 |

## 機能種別

デバッグ情報解析 / データ変換 / ファイル操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| サブコマンド | enum | Yes | dump/bytes/diadump/pretty/yaml2pdb/pdb2yaml/merge/explain/export | 有効なサブコマンド名 |
| 入力ファイル | string | Yes | 操作対象のPDBファイルパス | ファイルが存在すること |
| -types | flag | No | 型レコードをダンプ（dumpサブコマンド） | - |
| -symbols | flag | No | モジュールシンボルをダンプ（dumpサブコマンド） | - |
| -globals | flag | No | グローバルシンボルをダンプ（dumpサブコマンド） | - |
| -publics | flag | No | パブリックシンボルをダンプ（dumpサブコマンド） | - |
| -all | flag | No | すべての情報をダンプ（dumpサブコマンド） | - |
| -native | flag | No | DIA APIの代わりにネイティブPDBリーダーを使用 | - |
| -pdb | string | No | 出力PDBファイルパス（yaml2pdb/mergeサブコマンド） | - |

### 入力データソース

- ファイルシステム上のPDBファイル
- YAMLファイル（yaml2pdbサブコマンド用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ダンプ出力 | テキスト | PDBファイルの内容を人間が読める形式で出力 |
| YAML出力 | YAML | PDBファイルの構造をYAML形式で出力 |
| PDBファイル | バイナリ | 生成またはマージされたPDBファイル |
| バイナリデータ | バイナリ | ストリームのエクスポート結果 |

### 出力先

- 標準出力（ダンプ・YAML出力）
- 指定されたファイル（PDB生成・エクスポート）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数解析
   └─ サブコマンドとオプションの解析

2. サブコマンドに応じた処理分岐
   ├─ dump: PDBファイルをロードしDumpOutputStyleで出力
   ├─ bytes: PDBファイルのバイナリデータを表示
   ├─ pretty: セマンティックな型・シンボル情報を表示
   ├─ yaml2pdb: YAMLからPDBFileBuilderで生成
   ├─ pdb2yaml: YAMLOutputStyleでYAML形式出力
   ├─ merge: 複数PDBの型情報をマージ
   ├─ explain: ExplainOutputStyleでオフセットの意味を説明
   └─ export: 指定ストリームをファイルに出力

3. 結果の出力
   └─ 標準出力またはファイル
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C{サブコマンド?}
    C -->|dump| D[dumpRaw]
    C -->|bytes| E[dumpBytes]
    C -->|pretty| F[dumpPretty]
    C -->|yaml2pdb| G[yamlToPdb]
    C -->|pdb2yaml| H[pdb2Yaml]
    C -->|merge| I[mergePdbs]
    C -->|explain| J[explain]
    C -->|export| K[exportStream]
    D --> L[終了]
    E --> L
    F --> L
    G --> L
    H --> L
    I --> L
    J --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-1 | -allオプション | -allを指定すると主要なすべてのダンプオプションが有効になる | dumpサブコマンド |
| BR-62-2 | マージ入力数 | mergeサブコマンドには最低2つの入力ファイルが必要 | mergeサブコマンド |
| BR-62-3 | 出力ファイル名 | yaml2pdbで-pdb未指定時は入力ファイル名.pdbになる | yaml2pdbサブコマンド |

### 計算ロジック

特になし

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

該当なし（データベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル読み込みエラー | PDBファイルが読み込めない | ファイル名とエラーメッセージを表示し終了 |
| - | 無効なPDBエラー | 入力ファイルが有効なPDBフォーマットでない | エラーメッセージを表示し終了 |
| - | 入力不足エラー | mergeで入力ファイルが2つ未満 | エラーメッセージを表示し終了 |
| - | YAML解析エラー | yaml2pdbで入力YAMLが不正 | エラーメッセージを表示し終了 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

特に定義なし（PDBファイルのサイズに依存）

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

- 入力ファイルへの読み取りアクセス権限が必要
- 出力ファイルへの書き込みアクセス権限が必要

## 備考

- Windows環境ではDIA（Debug Interface Access）APIも利用可能（-nativeオプションで無効化）
- PDBフォーマットはMSF（Multi-Stream Format）コンテナ内にCodeView形式のデバッグ情報を格納

---

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

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

### 推奨読解順序

#### Step 1: メインプログラムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | llvm-pdbutil.cpp | `llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp` | サブコマンド定義とメイン処理フロー |

**主要処理フロー**:
1. **103-128行目**: サブコマンド（cl::SubCommand）の定義
2. **1496-1502行目**: main関数のエントリーポイント
3. **1521-1548行目**: dumpサブコマンドの-allオプション展開
4. **1617-1680行目**: サブコマンドに応じた処理分岐

#### Step 2: 出力スタイルクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DumpOutputStyle.cpp | `llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp` | dumpサブコマンドの出力処理 |
| 2-2 | YAMLOutputStyle.cpp | `llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp` | pdb2yamlサブコマンドの出力処理 |
| 2-3 | BytesOutputStyle.cpp | `llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp` | bytesサブコマンドの出力処理 |

#### Step 3: PDB生成処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-pdbutil.cpp | `llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp` | yamlToPdb関数(784-925行目) |

**読解のコツ**: yamlToPdb関数はYAMLからPDBを生成する処理。PDBFileBuilderを使用して各ストリーム（Info, Dbi, Tpi, Ipi等）を構築している。

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

```
main()
    │
    ├─ cl::ParseCommandLineOptions()
    │
    ├─ dumpRaw() [dumpサブコマンド]
    │      └─ DumpOutputStyle::dump()
    │
    ├─ dumpBytes() [bytesサブコマンド]
    │      └─ BytesOutputStyle::dump()
    │
    ├─ dumpPretty() [prettyサブコマンド]
    │      ├─ loadDataForPDB()
    │      └─ TypeDumper/FunctionDumper/etc.
    │
    ├─ yamlToPdb() [yaml2pdbサブコマンド]
    │      ├─ yaml::Input
    │      └─ PDBFileBuilder
    │
    ├─ pdb2Yaml() [pdb2yamlサブコマンド]
    │      └─ YAMLOutputStyle::dump()
    │
    ├─ mergePdbs() [mergeサブコマンド]
    │      ├─ MergingTypeTableBuilder
    │      └─ PDBFileBuilder
    │
    ├─ explain() [explainサブコマンド]
    │      └─ ExplainOutputStyle::dump()
    │
    └─ exportStream() [exportサブコマンド]
           └─ MappedBlockStream
```

### データフロー図

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

PDBファイル ───────▶ NativeSession ────────▶ ダンプテキスト
                          │
                          ▼
                    DumpOutputStyle/
                    BytesOutputStyle/
                    PrettyPrinters

YAMLファイル ──────▶ PDBFileBuilder ────────▶ PDBファイル
                          │
                          ├─ InfoBuilder
                          ├─ DbiBuilder
                          ├─ TpiBuilder
                          └─ IpiBuilder

PDBファイル1 ──┐
              ├──▶ MergingTypeTableBuilder ─▶ マージPDB
PDBファイル2 ──┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-pdbutil.cpp | `llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp` | ソース | メインプログラム |
| llvm-pdbutil.h | `llvm/tools/llvm-pdbutil/llvm-pdbutil.h` | ヘッダ | 共通定義 |
| DumpOutputStyle.cpp | `llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp` | ソース | dumpサブコマンド出力 |
| BytesOutputStyle.cpp | `llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp` | ソース | bytesサブコマンド出力 |
| YAMLOutputStyle.cpp | `llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp` | ソース | YAML出力 |
| ExplainOutputStyle.cpp | `llvm/tools/llvm-pdbutil/ExplainOutputStyle.cpp` | ソース | explainサブコマンド |
| PdbYaml.cpp | `llvm/tools/llvm-pdbutil/PdbYaml.cpp` | ソース | YAML構造定義 |
| MinimalTypeDumper.cpp | `llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp` | ソース | 型情報ダンプ |
| MinimalSymbolDumper.cpp | `llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp` | ソース | シンボルダンプ |
| CMakeLists.txt | `llvm/tools/llvm-pdbutil/CMakeLists.txt` | ビルド | ビルド設定 |
