# 機能設計書 57-PDBライター

## 概要

本ドキュメントは、F#コンパイラにおけるポータブルPDB（Program Database）ファイル生成機能について記述する。

### 本機能の処理概要

F#コンパイラが生成するアセンブリに対応するデバッグ情報（PDB）ファイルを生成する機能を提供する。ポータブルPDB形式をサポートし、クロスプラットフォームでのデバッグを可能にする。

**業務上の目的・背景**：デバッグ情報はソースコードとコンパイル済みバイナリを関連付けるために必要な情報である。ポータブルPDBはECMA-335拡張として標準化された形式で、Windows以外のプラットフォームでもデバッグが可能。

**機能の利用シーン**：
- F#コンパイラでのデバッグビルド
- Visual Studioでのデバッグセッション
- SourceLink対応のデバッグ
- 埋め込みPDBの生成

**主要な処理内容**：
1. ドキュメント情報の記録（ソースファイル名、チェックサム）
2. シーケンスポイントの記録（ソース位置とILオフセットの対応）
3. ローカル変数情報の記録
4. スコープ情報の記録
5. インポート情報の記録
6. SourceLinkの埋め込み
7. 埋め込みソースの圧縮・格納

**関連システム・外部連携**：
- System.Reflection.Metadata（メタデータビルダー）
- Visual Studioデバッガー
- SourceLinkサーバー

**権限による制御**：なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | デバッガーウィンドウ | 参照画面 | ブレークポイント、ステップ実行 |

## 機能種別

データ生成 / デバッグ情報

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| info | PdbData | Yes | PDBデータ構造 | - |
| embedAllSource | bool | No | 全ソース埋め込み | - |
| embedSourceList | string list | No | 埋め込むソースリスト | - |
| sourceLink | string | No | SourceLinkファイルパス | - |
| checksumAlgorithm | HashAlgorithm | No | チェックサムアルゴリズム | Sha1/Sha256 |
| pathMap | PathMap | No | パスマッピング | - |

### PdbData構造

| フィールド | 型 | 説明 |
|-----------|-----|------|
| EntryPoint | int32 option | エントリーポイントトークン |
| Timestamp | int32 | タイムスタンプ |
| ModuleID | byte[] | モジュールID（GUID） |
| Documents | PdbDocumentData[] | ドキュメント情報 |
| Methods | PdbMethodData[] | メソッド情報 |
| TableRowCounts | int[] | テーブル行数 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pdbファイル | .pdb | ポータブルPDBファイル |
| debugDirectory | idd[] | デバッグディレクトリエントリ |

### 出力先

- ファイルシステム（.pdb）
- PEファイル内（埋め込みPDB時）

## 処理フロー

### 処理シーケンス

```
1. PdbDataの前処理
   └─ メソッドのソート（トークン順）
   └─ ドキュメントのソート（パス順）

2. Documentテーブル構築
   └─ ドキュメント名のシリアライズ
   └─ チェックサムの計算
   └─ 言語GUIDの設定

3. MethodDebugInformationテーブル構築
   └─ シーケンスポイントのエンコード
   └─ ドキュメントハンドルの関連付け

4. LocalScopeテーブル構築
   └─ スコープ階層のエンコード
   └─ ローカル変数の関連付け

5. カスタムデバッグ情報
   └─ 埋め込みソース（オプション）
   └─ SourceLink（オプション）

6. PDBファイル出力
   └─ メタデータのシリアライズ
   └─ 圧縮（埋め込み時）
```

### フローチャート

```mermaid
flowchart TD
    A[開始: PDB生成] --> B[PdbDataソート]
    B --> C[Documentテーブル構築]
    C --> D[MethodDebugInformation構築]
    D --> E[LocalScope構築]
    E --> F{埋め込みソース?}
    F -->|Yes| G[ソース圧縮・埋め込み]
    F -->|No| H[SourceLink処理]
    G --> H
    H --> I{埋め込みPDB?}
    I -->|Yes| J[PDB圧縮・PE埋め込み]
    I -->|No| K[PDBファイル出力]
    J --> L[デバッグディレクトリ生成]
    K --> L
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | SHA1/SHA256 | チェックサムアルゴリズムは設定可能 | 常時 |
| BR-57-02 | ソース圧縮閾値 | 200バイト未満のソースは圧縮しない | embedSource時 |
| BR-57-03 | 決定論的PDB | パスはpathMapで正規化 | deterministic時 |
| BR-57-04 | 言語GUID | F#言語GUID: AB4F38C9-B6E6-43ba-BE3B-58080B2CCCE3 | 常時 |

### 計算ロジック

**ドキュメント名エンコーディング**:
- パス区切り文字（/または\）を先頭1バイトに記録
- 各パス部分をBlobヒープに格納し、インデックスを圧縮整数で記録

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IOException | 例外 | PDBファイル書き込み失敗 | パス/権限確認 |
| - | 警告 | ソースファイルが見つからない | ファイル確認 |

### リトライ仕様

本機能にリトライ機構はない。

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

該当なし

## パフォーマンス要件

- DeflateStreamでのソース圧縮
- BlobBuilderによる効率的なバッファ管理
- 並行性: ドキュメント処理は順次（ソート順依存）

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

- ソースコード埋め込み時は情報漏洩に注意
- SourceLinkのURLは外部公開可能であること

## 備考

- ポータブルPDBはECMA-335のメタデータ形式を使用
- 埋め込みPDBはPE内のデバッグディレクトリに格納
- IMAGE_DEBUG_TYPE_CODEVIEW (2) でPDBパス参照
- IMAGE_DEBUG_TYPE_EMBEDDEDPDB (17) で埋め込みPDB

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | PdbDocumentData型（59行目）でドキュメント情報を理解 |
| 1-2 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | PdbLocalVar型（61-67行目）でローカル変数情報を理解 |
| 1-3 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | PdbMethodScope型（81-88行目）でスコープ構造を理解 |
| 1-4 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | PdbDebugPoint型（97-108行目）でシーケンスポイントを理解 |
| 1-5 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | PdbData型（138-146行目）でPDBデータ全体を理解 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | PortablePdbGenerator（339行目）がPDB生成のメインクラス |
| 2-2 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | pdbGetDebugInfo関数（280-305行目）でデバッグディレクトリ情報を理解 |

#### Step 3: ドキュメント処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | serializeDocumentName関数（351-370行目）でドキュメント名エンコードを理解 |
| 3-2 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | checkSum関数（170-182行目）でチェックサム計算を理解 |
| 3-3 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | includeSource関数（392-418行目）でソース埋め込みを理解 |

#### Step 4: デバッグ情報生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | pdbGetCvDebugInfo関数（198-224行目）でCodeViewデバッグ情報を理解 |
| 4-2 | ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | pdbGetEmbeddedPdbDebugInfo関数（228-249行目）で埋め込みPDBを理解 |

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

```
PortablePdbGenerator
    │
    ├─ sortMethods (メソッドソート)
    │
    ├─ documentIndex構築
    │      ├─ serializeDocumentName
    │      ├─ checkSum
    │      └─ includeSource (オプション)
    │
    ├─ MethodDebugInformation構築
    │      └─ serializeSequencePoints
    │
    ├─ LocalScope構築
    │      ├─ serializeLocalScope
    │      └─ serializeImports
    │
    └─ pdbGetDebugInfo
           ├─ pdbGetCvDebugInfo
           ├─ pdbChecksumDebugInfo
           ├─ pdbGetEmbeddedPdbDebugInfo (オプション)
           └─ pdbGetPdbDebugDeterministicInfo (オプション)
```

### データフロー図

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

PdbData              ──▶  sortMethods               ──▶  ソート済みメソッド
       │
       ▼
ILSourceDocument     ──▶  serializeDocumentName     ──▶  DocumentHandle
       │
       ▼
ソースファイル       ──▶  checkSum                  ──▶  チェックサム
       │
       ▼
PdbMethodData        ──▶  MethodDebugInfo構築       ──▶  シーケンスポイント
       │
       ▼
PdbMethodScope       ──▶  LocalScope構築            ──▶  スコープ/ローカル
       │
       ▼
メタデータ           ──▶  シリアライズ              ──▶  PDBバイト列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ilwritepdb.fs | `src/Compiler/AbstractIL/ilwritepdb.fs` | ソース | PDBライターの中核実装 |
| ilwrite.fs | `src/Compiler/AbstractIL/ilwrite.fs` | ソース | ILライター（PDB生成呼び出し元） |
