# 機能設計書 69-llvm-gsymutil

## 概要

本ドキュメントは、LLVM llvm-gsymutil ツールの機能設計について記載する。llvm-gsymutilは、GSYM（Generic Symbol）フォーマットのダンプ、作成、アドレス検索を行うツールである。

### 本機能の処理概要

llvm-gsymutilは、コンパクトなシンボル情報フォーマットであるGSYMファイルを扱うユーティリティである。DWARFデバッグ情報からGSYMファイルを生成したり、GSYMファイル内のアドレス検索を行ったりできる。GSYMはシンボリケーション（アドレスからソース位置への変換）に特化した軽量フォーマットである。

**業務上の目的・背景**：クラッシュレポートのシンボリケーションにおいて、完全なDWARFデバッグ情報は大きすぎることがある。GSYMは必要最小限の情報のみを保持し、高速なアドレス検索を可能にする。モバイルアプリやサーバーアプリケーションのクラッシュ解析に活用される。

**機能の利用シーン**：
- DWARFデバッグ情報からGSYMファイルの生成
- GSYMファイルの内容ダンプ
- アドレスからソース位置への検索（シンボリケーション）
- 複数アドレスの一括検索
- マージされた関数の検索

**主要な処理内容**：
1. --convert: ELF/Mach-OからGSYMへの変換
2. アドレス検索: GSYMファイル内のアドレス検索
3. ダンプ: GSYMファイルの内容表示
4. --verify: 変換結果の検証
5. --merged-functions: マージされた関数の検索

**関連システム・外部連携**：LLVM DebugInfo/GSYM ライブラリ、DWARF

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

## 関連画面

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

## 機能種別

デバッグ情報変換 / シンボリケーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| 入力ファイル | string[] | No | GSYMファイル（ダンプ/検索時） | - |
| --convert | path | No | 変換元ファイル（ELF/Mach-O） | - |
| --out-file | path | No | 出力GSYMファイルパス | - |
| --address | addr | No | 検索アドレス（複数指定可） | 16進数 |
| --addresses-from-stdin | flag | No | 標準入力からアドレスを読み込み | - |
| --arch | arch | No | フィルタするアーキテクチャ | 有効なアーキテクチャ名 |
| --verify | flag | No | 変換結果を検証 | --convert時のみ |
| --verbose | flag | No | 詳細出力 | - |
| --quiet | flag | No | 進捗メッセージを抑制 | - |
| --num-threads | uint | No | スレッド数（デフォルト: 自動） | - |
| --segment-size | uint | No | セグメントサイズ | - |
| --merged-functions | flag | No | マージされた関数を検索 | - |
| --merged-functions-filter | regex | No | マージ関数のフィルタパターン | 正規表現 |
| --json-summary-file | path | No | JSONサマリー出力ファイル | - |
| --callsites-yaml-file | path | No | コールサイト情報YAMLファイル | - |
| --dwarf-callsites | flag | No | DWARFからコールサイト情報を読み込み | - |

### 入力データソース

- GSYMファイル
- ELFオブジェクトファイル
- Mach-Oオブジェクトファイル
- ユニバーサルバイナリ
- dSYMバンドル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| GSYMファイル | バイナリ | 変換されたGSYMファイル |
| ダンプ出力 | テキスト | GSYMファイルの内容 |
| 検索結果 | テキスト | アドレスに対応するソース位置 |
| JSONサマリー | JSON | エラーカテゴリとカウント |

### 出力先

- 標準出力（ダンプ/検索結果）
- 指定ファイル（--out-file）
- JSONファイル（--json-summary-file）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数解析
   └─ parseArgs()

2. 動作モード判定
   ├─ --convert指定: 変換モード
   ├─ --addresses-from-stdin: 標準入力検索モード
   └─ 入力ファイル指定: ダンプ/検索モード

3. 変換モード処理
   └─ convertFileToGSYM()
       ├─ handleFileConversionToGSYM()
       ├─ handleObjectFile()
       │      ├─ DwarfTransformer.convert()
       │      ├─ ObjectFileTransformer.convert()
       │      ├─ GsymCreator.finalize()
       │      └─ GsymCreator.save()
       └─ [--verify] DwarfTransformer.verify()

4. 検索モード処理
   └─ GsymReader.lookup() / GsymReader.lookupAll()

5. ダンプモード処理
   └─ GsymReader.dump()
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C{モード?}
    C -->|--convert| D[convertFileToGSYM]
    C -->|--addresses-from-stdin| E[標準入力から検索]
    C -->|入力ファイル| F{--address指定?}
    D --> G[handleObjectFile]
    G --> H[DwarfTransformer.convert]
    H --> I[GsymCreator.save]
    I --> J{--verify?}
    J -->|Yes| K[DwarfTransformer.verify]
    J -->|No| L[終了]
    K --> L
    E --> M[GsymReader.lookup]
    M --> L
    F -->|Yes| N[GsymReader.lookup]
    F -->|No| O[GsymReader.dump]
    N --> L
    O --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-69-1 | 変換時入力制限 | --convert時は他の入力ファイルを指定不可 | --convert時 |
| BR-69-2 | 標準入力検索制限 | --addresses-from-stdin時は入力ファイル/--address不可 | --addresses-from-stdin時 |
| BR-69-3 | デフォルト出力ファイル名 | --out-file未指定時は入力ファイル名.gsym | --convert時 |
| BR-69-4 | マージ関数フィルタ必須オプション | --merged-functions-filterは--merged-functionsが必要 | フィルタ指定時 |
| BR-69-5 | ベースアドレス自動検出 | ELF: 最初のPT_LOADのp_vaddr、Mach-O: __TEXTセグメントのvmaddr | 変換時 |
| BR-69-6 | スレッド数デフォルト | 未指定時はhardware_concurrency()を使用 | --num-threads未指定時 |

### 計算ロジック

- ベースアドレス計算（ELF）: 最初のPT_LOADセグメントのp_vaddr
- ベースアドレス計算（Mach-O）: __TEXTセグメントのvmaddr

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 変換エラー | DWARF変換に失敗 | エラーメッセージを表示し終了 |
| 1 | ファイル読み込みエラー | 入力ファイルが読み込めない | エラーメッセージを表示し終了 |
| 1 | 検索エラー | アドレスが見つからない | エラーメッセージを表示 |
| 1 | オプション競合 | --convert時に入力ファイル指定 | エラーメッセージを表示し終了 |
| 1 | アドレス不正 | 無効なアドレス形式 | エラーメッセージを表示し終了 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

- マルチスレッド変換をサポート（--num-threadsで制御）
- セグメント分割出力をサポート（--segment-size）

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

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

## 備考

- GSYMはLLVMプロジェクトで開発されたコンパクトなシンボル情報フォーマット
- DWARFの完全な情報ではなく、シンボリケーションに必要な最小限の情報のみを保持
- インライン関数情報もサポート

---

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

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

### 推奨読解順序

#### Step 1: コマンドラインオプションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | llvm-gsymutil.cpp | `llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp` | グローバル変数（88-103行目） |
| 1-2 | llvm-gsymutil.cpp | `llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp` | parseArgs関数（105-215行目） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-gsymutil.cpp | `llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp` | llvm_gsymutil_main関数（600-717行目） |

**主要処理フロー**:
1. **606-608行目**: parseArgs()で引数解析
2. **613-651行目**: --convert時のconvertFileToGSYM()
3. **654-697行目**: --addresses-from-stdin時の標準入力処理
4. **700-715行目**: GSYMファイルのダンプ/検索

#### Step 3: 変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-gsymutil.cpp | `llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp` | convertFileToGSYM関数（503-528行目） |
| 3-2 | llvm-gsymutil.cpp | `llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp` | handleObjectFile関数（346-440行目） |

**主要処理フロー**:
- **351行目**: GsymCreator生成
- **357-358行目**: ベースアドレス設定
- **375-382行目**: DWARFContext作成
- **391行目**: DwarfTransformer作成
- **396行目**: DT.convert()でDWARF変換
- **407行目**: ObjectFileTransformer.convert()でシンボル変換
- **418行目**: Gsym.finalize()でファイナライズ
- **429行目**: Gsym.save()で保存

#### Step 4: 検索処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | llvm-gsymutil.cpp | `llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp` | doLookup関数（530-598行目） |

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

```
llvm_gsymutil_main()
    │
    ├─ parseArgs()
    │
    ├─ [--convert]
    │      └─ convertFileToGSYM()
    │             └─ handleFileConversionToGSYM()
    │                    └─ handleBuffer()
    │                           └─ handleObjectFile()
    │                                  ├─ getImageBaseAddress()
    │                                  ├─ DWARFContext::create()
    │                                  ├─ DwarfTransformer.convert()
    │                                  ├─ ObjectFileTransformer.convert()
    │                                  ├─ GsymCreator.finalize()
    │                                  ├─ GsymCreator.save()
    │                                  └─ [--verify] DwarfTransformer.verify()
    │
    ├─ [--addresses-from-stdin]
    │      ├─ GsymReader::openFile()
    │      └─ doLookup()
    │
    └─ [GSYMファイル]
           ├─ GsymReader::openFile()
           ├─ [--address] doLookup()
           └─ [else] GsymReader.dump()
```

### データフロー図

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

ELF/Mach-Oファイル
       │
       ▼
DWARFContext::create()
       │
       ▼
DwarfTransformer ──────▶ GsymCreator
       │                      │
       │                      ▼
       │               finalize()
       │                      │
       │                      ▼
       │                 save() ─────────────────▶ GSYMファイル
       │
       └──[--verify]───▶ verify()


GSYMファイル
       │
       ▼
GsymReader::openFile()
       │
       ▼
┌──────┴──────┐
│             │
▼             ▼
dump()     lookup()
│             │
▼             ▼
内容表示    検索結果 ─────────────────────▶ 標準出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-gsymutil.cpp | `llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp` | ソース | メインプログラム |
| Opts.td | `llvm/tools/llvm-gsymutil/Opts.td` | 定義 | コマンドラインオプション定義 |
| CMakeLists.txt | `llvm/tools/llvm-gsymutil/CMakeLists.txt` | ビルド | ビルド設定 |
