# 機能設計書 64-libunwind

## 概要

本ドキュメントは、Zigコンパイラにおけるスタック巻き戻しライブラリ（libunwind）の統合機能の設計を記述する。この機能は、例外処理やスタックトレースの取得に必要なスタック巻き戻し機能を提供する。

### 本機能の処理概要

libunwind機能は、LLVM libunwindをZigコンパイラ内でビルドし、プログラムの実行時にスタックフレームを巻き戻す機能を提供する。これは主にC++の例外処理や、デバッグ時のスタックトレース取得に使用される。Zigのエラー処理やスタックトレース表示においても重要な役割を果たす。

**業務上の目的・背景**：プログラムのデバッグや例外処理においてスタックトレースは必須の情報である。libunwindを内蔵することで、ZigはプラットフォームごとのABI（DWARF、SEH、ARM EHABI等）に対応したスタック巻き戻し機能を提供し、ポータブルなエラーハンドリングを実現する。

**機能の利用シーン**：
- C++例外のキャッチとスタック巻き戻し
- パニック時のスタックトレース表示
- デバッガでのスタックフレーム解析
- シグナルハンドラからのスタック情報取得

**主要な処理内容**：
1. libunwindソースファイルのコンパイル
2. プラットフォーム固有の巻き戻しレジスタ保存/復元コードのコンパイル
3. 静的ライブラリの生成
4. アンワインドテーブルの設定

**関連システム・外部連携**：
- libc++abi（C++例外処理）
- デバッガ（GDB、LLDB）
- カーネル（シグナル処理）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面なし（内部ライブラリ） |

## 機能種別

ライブラリビルド / ランタイムサポート

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| comp | *Compilation | Yes | コンパイル設定情報 | 有効なコンパイル設定 |
| prog_node | Progress.Node | Yes | 進捗表示ノード | 有効なノード |

### 入力データソース

- `lib/libunwind/src/` - libunwindソースファイル
- ターゲット設定情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| libunwind_static_lib | CrtFile | libunwind静的ライブラリ |

### 出力先

- グローバルキャッシュディレクトリ

## 処理フロー

### 処理シーケンス

```
1. 設定解決
   └─ ターゲットとアンワインドテーブル設定の決定

2. ソースファイルコンパイル
   ├─ libunwind.cpp（メイン実装）
   ├─ Unwind-EHABI.cpp（ARM EHABI）
   ├─ Unwind-seh.cpp（Windows SEH）
   ├─ UnwindLevel1.c（レベル1 API）
   └─ UnwindRegistersRestore.S / UnwindRegistersSave.S

3. 静的ライブラリ生成
   └─ libunwind.aの作成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{LLVM利用可能?}
    B -->|No| C[エラー返却]
    B -->|Yes| D[設定解決]
    D --> E[アンワインドテーブル設定]
    E --> F{x86 Windows?}
    F -->|Yes| G[テーブルなし]
    F -->|No| H[asyncテーブル]
    G --> I[ソースファイル収集]
    H --> I
    I --> J[コンパイルフラグ設定]
    J --> K{デバッグモード?}
    K -->|Yes| L[-D_DEBUG追加]
    K -->|No| M[スキップ]
    L --> N[シングルスレッド?]
    M --> N
    N -->|Yes| O[-D_LIBUNWIND_HAS_NO_THREADS]
    N -->|No| P[スキップ]
    O --> Q[サブコンパイル実行]
    P --> Q
    Q --> R[静的ライブラリ生成]
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-64-01 | アンワインドテーブル | 古い32ビットx86 WindowsではSEHがテーブルを使わない | cpu.arch == .x86 かつ os.tag == .windows |
| BR-64-02 | ARM HFサポート | ARM hardfloatターゲットでCOMPILER_RT_ARMHF_TARGETを定義 | isArm() かつ float() == .hard |
| BR-64-03 | スレッド無効化 | シングルスレッドモードでスレッドサポートを無効化 | !any_non_single_threaded |
| BR-64-04 | ネイティブビルド | _LIBUNWIND_IS_NATIVE_ONLYを常に定義 | 常時 |

### 計算ロジック

該当なし

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

### 操作別データベース影響一覧

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ZigCompilerNotBuiltWithLLVMExtensions | 未サポート | LLVMなしでビルドされたZig | LLVM有効のZigを使用 |
| OutOfMemory | メモリ不足 | ビルド中のメモリ不足 | メモリ増設 |
| AlreadyReported | エラー報告済み | サブコンパイル失敗 | 詳細エラーを確認 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 関数セクション分離によるコードサイズ最適化
- データセクション分離
- 高速なスタック巻き戻し

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

- シンボル可視性制御（hidden）
- スタック保護の適切な設定
- 非実行可能スタック（--noexecstack）

## 備考

- libunwindは自身のスタックフレームを巻き戻す必要があるため、async アンワインドテーブルが必要
- Windows x86ではSEHがテーブルを使わないため例外
- WASIターゲット向けのUnwind-wasm.cも含まれる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | libunwind.zig | `src/libs/libunwind.zig` | ソースファイルリストとビルドエラー型 |

**読解のコツ**:
- `unwind_src_list`はコンパイル対象のソースファイルリスト
- `BuildError`はビルド処理で発生しうるエラー型

**主要処理フロー**:
- **11-15行目**: BuildError型定義
- **194-205行目**: unwind_src_listリスト

#### Step 2: ビルド処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | libunwind.zig | `src/libs/libunwind.zig` | buildStaticLib関数 |

**主要処理フロー**:
- **17-192行目**: buildStaticLib - libunwindのビルド処理全体
- **32-33行目**: アンワインドテーブル設定
- **89-142行目**: ソースファイルごとのコンパイルフラグ設定

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

```
Compilation
    │
    └─ buildStaticLib
           ├─ Config.resolve (設定解決)
           ├─ Module.create (モジュール作成)
           ├─ ソースファイル処理
           │      ├─ libunwind.cpp
           │      ├─ Unwind-EHABI.cpp
           │      ├─ Unwind-seh.cpp
           │      ├─ UnwindLevel1.c
           │      ├─ UnwindLevel1-gcc-ext.c
           │      ├─ Unwind-sjlj.c
           │      ├─ Unwind-wasm.c
           │      ├─ UnwindRegistersRestore.S
           │      ├─ UnwindRegistersSave.S
           │      └─ gcc_personality_v0.c
           ├─ Compilation.create (サブコンパイル)
           └─ updateSubCompilation
```

### データフロー図

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

lib/libunwind/src/*.cpp ──▶ buildStaticLib ────────────▶ libunwind.a
lib/libunwind/src/*.c                │
lib/libunwind/src/*.S                │
                                     ├── アンワインドテーブル設定
                                     ├── コンパイルフラグ設定
                                     │      ├─ C: -std=c99, -fexceptions
                                     │      └─ C++: -fno-exceptions, -fno-rtti
                                     └── サブコンパイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| libunwind.zig | `src/libs/libunwind.zig` | ソース | libunwindビルドの実装 |
| libunwind.cpp | `lib/libunwind/src/libunwind.cpp` | ソース | メインAPI実装 |
| Unwind-EHABI.cpp | `lib/libunwind/src/Unwind-EHABI.cpp` | ソース | ARM EHABI対応 |
| Unwind-seh.cpp | `lib/libunwind/src/Unwind-seh.cpp` | ソース | Windows SEH対応 |
| UnwindLevel1.c | `lib/libunwind/src/UnwindLevel1.c` | ソース | Level 1 API |
| UnwindRegistersRestore.S | `lib/libunwind/src/UnwindRegistersRestore.S` | アセンブリ | レジスタ復元 |
| UnwindRegistersSave.S | `lib/libunwind/src/UnwindRegistersSave.S` | アセンブリ | レジスタ保存 |
| include/ | `lib/libunwind/include/` | ヘッダ | libunwindヘッダファイル |
