# 機能設計書 63-llvm-ifs

## 概要

本ドキュメントは、LLVM llvm-ifs ツールの機能設計について記載する。llvm-ifsは、Interface Stub（IFS）ファイルの生成・変換を行う共有ライブラリスタブ作成ツールである。

### 本機能の処理概要

llvm-ifsは、ELFバイナリやIFSファイル（YAML形式）からインターフェーススタブファイルを生成し、異なるフォーマット（IFS、ELF、TBD）への変換を行うツールである。共有ライブラリのABIインターフェースを抽出・管理するために使用される。

**業務上の目的・背景**：共有ライブラリを使用するソフトウェア開発において、実装の詳細を隠しつつABIを公開するためのスタブファイルが必要となる。llvm-ifsは、ELFバイナリからシンボル情報を抽出してスタブファイルを生成したり、複数のIFSファイルをマージしたりすることで、ライブラリのABI管理を支援する。また、macOS用のTBD（Text-Based Stub）フォーマットへの変換も可能である。

**機能の利用シーン**：
- 共有ライブラリのABIスタブファイル生成
- ELFバイナリからのインターフェース情報抽出
- 複数のIFSファイルのマージ
- IFS形式とELF形式の相互変換
- macOS TBD形式への変換

**主要な処理内容**：
1. ELFバイナリからのシンボル情報抽出とIFSStub構造体への変換
2. IFSファイル（YAML形式）の読み込みと解析
3. 複数入力ファイルのマージ処理
4. シンボルのフィルタリング（除外・未定義シンボル削除等）
5. 出力フォーマット（IFS/ELF/TBD）への変換と出力

**関連システム・外部連携**：LLVM InterfaceStubライブラリ、TextAPIライブラリ（TBD出力用）

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

## 関連画面

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

## 機能種別

ファイル変換処理 / シンボル抽出 / データマージ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| 入力ファイル | string | Yes | ELFバイナリまたはIFSファイルのパス | ファイルが存在すること |
| --input-format | enum | No | 入力フォーマット指定（IFS/ELF） | 有効なフォーマット名 |
| --output-format | enum | No | 出力フォーマット指定（IFS/ELF/TBD）※非推奨 | 有効なフォーマット名 |
| --output-elf | string | No | ELF形式の出力ファイルパス | - |
| --output-ifs | string | No | IFS形式の出力ファイルパス | - |
| --output-tbd | string | No | TBD形式の出力ファイルパス | - |
| --arch | enum | No | アーキテクチャオーバーライド | 有効なアーキテクチャ名 |
| --bitwidth | enum | No | ビット幅オーバーライド（32/64） | 32または64 |
| --endianness | enum | No | エンディアンオーバーライド（little/big） | littleまたはbig |
| --target | string | No | ターゲットトリプルオーバーライド | - |
| --soname | string | No | SOナームオーバーライド | - |
| --exclude | string | No | 除外するシンボルパターン（複数指定可） | - |
| --strip-undefined | flag | No | 未定義シンボルを削除 | - |
| --strip-needed | flag | No | 依存ライブラリ情報を削除 | - |
| --strip-size | flag | No | シンボルサイズ情報を削除 | - |
| --write-if-changed | flag | No | 変更がある場合のみ書き込み | - |

### 入力データソース

- ファイルシステム上のELFバイナリまたはIFS（YAML）ファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| IFSファイル | YAML | インターフェーススタブ情報（YAML形式） |
| ELFスタブ | バイナリ | ELF形式のスタブバイナリ |
| TBDファイル | テキスト | macOS用Text-Based Stubファイル |

### 出力先

- 指定された出力ファイル（--output-ifs/--output-elf/--output-tbd）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数解析
   └─ DriverConfig構造体にオプション情報を格納

2. 入力ファイルの読み込み
   └─ ELF形式の場合はreadELFFile、IFS形式の場合はreadIFSFromBufferで読み込み

3. 複数ファイルのマージ（複数入力時）
   └─ IfsVersion、Target、SoName、NeededLibsの一致確認
   └─ シンボルのマージと競合チェック

4. オプションによる変換処理
   └─ アーキテクチャ/エンディアン/ビット幅のオーバーライド
   └─ シンボルフィルタリング（除外パターン、未定義削除等）
   └─ SoNameのオーバーライド

5. 出力フォーマットへの変換と出力
   └─ IFS: writeIFS()でYAML出力
   └─ ELF: writeBinaryStub()でELFスタブ生成
   └─ TBD: writeTbdStub()でTBD形式出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C[入力ファイル読み込み]
    C --> D{複数入力?}
    D -->|Yes| E[マージ処理]
    D -->|No| F[オプション適用]
    E --> F
    F --> G{出力形式?}
    G -->|IFS| H[writeIFS]
    G -->|ELF| I[writeBinaryStub]
    G -->|TBD| J[writeTbdStub]
    H --> K[終了]
    I --> K
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-63-1 | 複数入力時のフォーマット | 複数入力ファイル時は入力フォーマットはIFSに限定される | 入力ファイル数>1 |
| BR-63-2 | マージ時のバージョンチェック | マージ時、IfsVersionのメジャーバージョンは一致が必須 | マージ処理時 |
| BR-63-3 | マージ時のTarget/SoName一致 | マージ時、空でないTarget/SoNameは一致が必須 | マージ処理時 |
| BR-63-4 | TBD出力時のTriple必須 | TBD形式出力時はTarget.Tripleが定義されている必要がある | TBD出力時 |
| BR-63-5 | 現行IFSバージョン | サポートするIFSバージョンは3.0 | 常時 |

### 計算ロジック

特になし

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バージョン不一致 | マージ時にIfsVersionのメジャーバージョンが異なる | エラーメッセージを表示し終了 |
| - | ターゲット不一致 | マージ時にTargetが異なる | エラーメッセージを表示し終了 |
| - | SoName不一致 | マージ時にSoNameが異なる | エラーメッセージを表示し終了 |
| - | 型不一致 | マージ時に同名シンボルの型が異なる | エラーメッセージを表示し終了 |
| - | Triple未定義 | TBD出力時にTripleが未定義 | エラーメッセージを表示し終了 |
| - | 出力未指定 | 出力先が指定されていない | エラーメッセージを表示し終了 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

特に定義なし

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

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

## 備考

- IFSフォーマットはYAML形式のインターフェーススタブ記述フォーマット
- --output-formatオプションは非推奨、代わりに--output-{FILE_FORMAT}オプションを使用

---

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

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

### 推奨読解順序

#### Step 1: オプション定義とデータ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Opts.td | `llvm/tools/llvm-ifs/Opts.td` | コマンドラインオプション定義 |
| 1-2 | llvm-ifs.cpp | `llvm/tools/llvm-ifs/llvm-ifs.cpp` | DriverConfig構造体（83-113行目） |

**読解のコツ**: DriverConfig構造体がすべてのオプション情報を保持。InputFormat、OutputFormatはオプショナルで、未指定時は入力ファイルから自動判定される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-ifs.cpp | `llvm/tools/llvm-ifs/llvm-ifs.cpp` | llvm_ifs_main関数（382-632行目） |

**主要処理フロー**:
1. **382-384行目**: エントリーポイント、引数解析
2. **388-390行目**: 複数入力時のフォーマット制限
3. **393-476行目**: 入力ファイルの読み込みとマージ処理ループ
4. **489-506行目**: オプション適用（SoName、フィルタリング等）
5. **508-630行目**: 出力フォーマットに応じた出力処理

#### Step 3: ファイル読み込み処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-ifs.cpp | `llvm/tools/llvm-ifs/llvm-ifs.cpp` | readInputFile関数（131-183行目） |

**主要処理フロー**:
- **144-153行目**: ELF形式としての読み込み試行
- **156-173行目**: IFS形式としての読み込み試行
- **175-182行目**: 両方失敗時のエラー処理

#### Step 4: 出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | llvm-ifs.cpp | `llvm/tools/llvm-ifs/llvm-ifs.cpp` | writeIFS関数（255-280行目） |
| 4-2 | llvm-ifs.cpp | `llvm/tools/llvm-ifs/llvm-ifs.cpp` | writeTbdStub関数（185-241行目） |

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

```
llvm_ifs_main()
    │
    ├─ parseArgs()
    │      └─ DriverConfigの構築
    │
    ├─ readInputFile() [各入力ファイルに対して]
    │      ├─ readELFFile()
    │      └─ readIFSFromBuffer()
    │
    ├─ マージ処理 [複数入力時]
    │      └─ シンボルの統合と競合チェック
    │
    ├─ overrideIFSTarget()
    │      └─ アーキテクチャ等のオーバーライド
    │
    ├─ filterIFSSyms()
    │      └─ シンボルフィルタリング
    │
    └─ 出力処理
           ├─ writeIFS() [IFS形式]
           ├─ writeBinaryStub() [ELF形式]
           └─ writeTbdStub() [TBD形式]
```

### データフロー図

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

ELFバイナリ ──────▶ readELFFile() ────┐
                                      ├──▶ IFSStub ──▶ マージ処理
IFSファイル ──────▶ readIFSFromBuffer()┘       │
                                               ▼
                                    オプション適用
                                    (フィルタ/オーバーライド)
                                               │
                                    ┌──────────┼──────────┐
                                    ▼          ▼          ▼
                               writeIFS  writeBinaryStub  writeTbdStub
                                    │          │          │
                                    ▼          ▼          ▼
                               .ifs/.yaml   .so/.o    .tbd
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-ifs.cpp | `llvm/tools/llvm-ifs/llvm-ifs.cpp` | ソース | メインプログラム |
| Opts.td | `llvm/tools/llvm-ifs/Opts.td` | 定義 | コマンドラインオプション定義 |
| ErrorCollector.cpp | `llvm/tools/llvm-ifs/ErrorCollector.cpp` | ソース | エラー収集ユーティリティ |
| ErrorCollector.h | `llvm/tools/llvm-ifs/ErrorCollector.h` | ヘッダ | エラー収集クラス定義 |
| CMakeLists.txt | `llvm/tools/llvm-ifs/CMakeLists.txt` | ビルド | ビルド設定 |
