# 機能設計書 42-LLDリンカ統合

## 概要

本ドキュメントは、ZigコンパイラにおけるLLD（LLVM Linker）との統合機能について記述する。LLDはLLVMプロジェクトの一部として開発された高速リンカであり、Zigはこれを活用してELF、COFF、WebAssembly形式の最終バイナリを生成する。

### 本機能の処理概要

LLDリンカ統合は、ZigコンパイラがLLVMバックエンドを使用してコンパイルしたオブジェクトファイルをリンクし、実行可能ファイル、動的ライブラリ、静的ライブラリを生成する機能である。

**業務上の目的・背景**：Zigはセルフホスティングコンパイラを目指しているが、現時点ではLLVMバックエンドを使用する場合にLLDが必要となる。LLDはクロスプラットフォーム対応、高速なリンク処理、LTO（Link Time Optimization）のサポートなど、多くの利点を持つ。Zigネイティブリンカの開発が進むまでの間、LLD統合は安定したバイナリ生成の基盤として機能する。

**機能の利用シーン**：
- LLVMバックエンドを使用したネイティブコードのコンパイル時
- リリースビルドでLTOを有効にした最適化時
- Windows COFF形式の実行可能ファイル生成時
- 外部C/C++ライブラリとのリンク時

**主要な処理内容**：
1. コンパイラが生成したオブジェクトファイルの収集
2. リンカコマンドライン引数の構築
3. LLDの子プロセスとしての起動
4. ELF/COFF/WASM形式固有のリンク処理
5. LTOパスの実行（有効時）
6. 最終バイナリの生成

**関連システム・外部連携**：
- LLVM/LLDリンカ
- システムlibc（glibc、musl、mingw、MSVC等）
- 外部ライブラリ（.a、.so、.lib、.dll等）

**権限による制御**：特になし（コンパイルオプションによる制御）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 実行ファイルビルド画面 | 補助機能 | LLDリンカとの統合処理 |

## 機能種別

リンク処理 / バイナリ生成 / 外部ツール連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ofmt | ObjectFormat | Yes | オブジェクト形式（elf/coff/wasm） | elf, coff, wasmのいずれか |
| output_mode | OutputMode | Yes | 出力モード（Exe/Lib/Obj） | 有効なOutputMode列挙値 |
| link_mode | LinkMode | Yes | リンクモード（static/dynamic） | static, dynamicのいずれか |
| objects | []ObjectInput | No | リンク対象オブジェクトファイル | 有効なオブジェクトファイルパス |
| libraries | []LibraryInput | No | リンク対象ライブラリ | 有効なライブラリパス |
| stack_size | u64 | No | スタックサイズ | デフォルト: 16MB |
| image_base | u64 | No | イメージベースアドレス | アーキテクチャ依存のデフォルト値 |
| lto | LtoMode | No | LTOモード | none, thin, fullのいずれか |

### 入力データソース

- Zigコンパイラが生成したオブジェクトファイル（.o、.obj）
- Cコンパイラが生成したオブジェクトファイル
- 静的ライブラリ（.a、.lib）
- 動的ライブラリ（.so、.dll）
- Windowsリソースファイル（.res）
- compiler_rt / ubsan_rt

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| executable | File | 実行可能バイナリ（ELF/PE/WASM形式） |
| shared_lib | File | 動的ライブラリ（.so/.dll） |
| static_lib | File | 静的ライブラリ（.a/.lib） |
| pdb | File | デバッグ情報ファイル（Windows、オプション） |
| implib | File | インポートライブラリ（Windows DLL用） |

### 出力先

指定された出力パスに各形式のバイナリファイルを生成

## 処理フロー

### 処理シーケンス

```
1. リンカ選択
   └─ ofmtに基づいてcoffLink/elfLink/wasmLinkを選択
2. 静的ライブラリ生成判定
   └─ static lib の場合は linkAsArchive へ
3. オブジェクトファイル収集
   └─ zcu_obj, c_objects, win32_resourcesを収集
4. コマンドライン構築
   └─ リンカフラグ、ライブラリパス、オブジェクトを追加
5. 依存ライブラリ追加
   └─ libc, libc++, libunwind, compiler_rt等
6. LLDプロセス起動
   └─ spawnLld関数で子プロセスとして実行
7. 結果検証
   └─ LLD終了コード確認、エラーメッセージ解析
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{output_mode?}
    B -->|Lib & static| C[linkAsArchive]
    B -->|Exe/DynLib| D{ofmt?}
    D -->|coff| E[coffLink]
    D -->|elf| F[elfLink]
    D -->|wasm| G[wasmLink]
    C --> H[llvm.WriteArchive]
    E --> I[LLDコマンドライン構築]
    F --> I
    G --> I
    I --> J[spawnLld]
    J --> K{成功?}
    K -->|Yes| L[終了]
    K -->|No| M[エラー処理]
    H --> L
    M --> N[LinkFailureエラー]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | 子プロセス実行 | LLDはライブラリとして動作せずexit()を呼ぶため子プロセスとして実行 | 常時 |
| BR-42-02 | LTOレベル | ReleaseSmallではlto-O2、ReleaseFast/SafeではltoーO3 | LTO有効時 |
| BR-42-03 | サブシステム推論 | Windows向けでは、エクスポートシンボルからサブシステムを推論 | COFF形式 |
| BR-42-04 | CRTリンク | libcリンク時はCRTオブジェクトを自動追加 | link_libc有効時 |

### 計算ロジック

**イメージベースアドレス計算**（COFF形式）:
- Exe, x86_64/aarch64: 0x140000000
- Exe, x86/thumb: 0x400000
- Lib, x86_64/aarch64: 0x180000000
- Lib, x86/thumb: 0x10000000

**スタックサイズ**:
- デフォルト: 16MB
- WASM freestanding: 1MB

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

該当なし（ファイルベースの処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| LinkFailure | リンクエラー | LLDがエラーを報告 | LLDエラーメッセージを解析して表示 |
| DllImportLibraryNotFound | ライブラリエラー | DLLインポートライブラリが見つからない | ライブラリパスを追加 |
| NoObjectsToLink | 入力エラー | リンク対象オブジェクトがない | ソースファイルを指定 |
| UnsupportedCoffArchitecture | アーキテクチャエラー | COFF非対応アーキテクチャ | 対応アーキテクチャを使用 |

### リトライ仕様

リンク処理はリトライなし（失敗時は即時エラー終了）

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

該当なし（ファイル生成は原子的に実行）

## パフォーマンス要件

- LTO有効時でも大規模プロジェクトで数分以内に完了
- 増分リンクは未サポート（LLDの制限）

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

- 入力オブジェクトファイルの妥当性検証
- 外部ライブラリの信頼性はユーザー責任
- コマンドライン引数のエスケープ処理

## 備考

- LLDはグローバル状態をリセットしないため、子プロセスとして実行される
- Zigネイティブリンカ（ELF2, COFF2等）が成熟すれば、LLD依存は削減される予定
- BPF、m68k、SPARCなど一部アーキテクチャはLLDの制限により特殊処理が必要

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Lld.zig | `src/link/Lld.zig` | Lld構造体とofmt union型（ELF/COFF/WASM設定を保持） |

**読解のコツ**:
- `base: link.File`フィールドで共通インターフェースを継承
- `ofmt`はunion型で、elf/coff/wasmそれぞれの設定を保持
- 各形式固有の設定は内部struct（Coff, Elf, Wasm）で定義

**主要処理フロー**:
1. **1-73行目**: Coff構造体 - Windows COFF/PE形式の設定
2. **74-159行目**: Elf構造体 - Linux ELF形式の設定
3. **160-198行目**: Wasm構造体 - WebAssembly形式の設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Lld.zig | `src/link/Lld.zig` | createEmpty関数とflush関数 |

**主要処理フロー**:
1. **200-249行目**: `createEmpty` - Lld構造体の初期化、ofmtに応じた設定
2. **253-283行目**: `flush` - リンク処理のエントリーポイント
3. **269-278行目**: 出力モードと形式に応じてlinkAsArchive/coffLink/elfLink/wasmLinkを選択

#### Step 3: 形式別リンク処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Lld.zig | `src/link/Lld.zig` | coffLink関数（Windows向け） |
| 3-2 | Lld.zig | `src/link/Lld.zig` | elfLink関数（Linux向け） |

**主要処理フロー（coffLink）**:
- **359-744行目**: Windows COFF/PE形式のリンク処理
- **413-420行目**: LLDはライブラリとして動作せずexit()を呼ぶため子プロセスとして実行
- **420行目**: linker_command = "lld-link"
- **610-677行目**: UEFIとWin32での設定分岐

**主要処理フロー（elfLink）**:
- **757-899行目以降**: Linux ELF形式のリンク処理
- **837行目**: linker_command = "ld.lld"
- **797-804行目**: BPF、m68k、SPARC等のLLD非対応アーキテクチャの特殊処理

#### Step 4: LLD起動処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Lld.zig | `src/link/Lld.zig` | spawnLld関数 |

**読解のコツ**:
- LLDは`comp.self_exe_path`（Zigコンパイラ自身）を子プロセスとして起動
- リンカサブコマンド（lld-link、ld.lld、wasm-ld）を引数として渡す
- これによりLLDのグローバル状態問題を回避

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

```
Compilation.zig (コンパイル処理)
    │
    └─ link.File.flush()
           │
           └─ Lld.flush()
                  │
                  ├─ linkAsArchive() [static lib]
                  │      └─ llvm.WriteArchive()
                  │
                  ├─ coffLink() [Windows]
                  │      └─ spawnLld("lld-link")
                  │
                  ├─ elfLink() [Linux/BSD]
                  │      └─ spawnLld("ld.lld")
                  │
                  └─ wasmLink() [WebAssembly]
                         └─ spawnLld("wasm-ld")
```

### データフロー図

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

Zigオブジェクト(.o)  ─┐
Cオブジェクト(.o)    ─┼──▶  Lld.flush()  ──▶  実行ファイル/ライブラリ
ライブラリ(.a/.so)   ─┤         │
compiler_rt          ─┘         │
                                ▼
                         spawnLld()
                                │
                                ▼
                         LLDプロセス
                         (lld-link/ld.lld/wasm-ld)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Lld.zig | `src/link/Lld.zig` | ソース | LLDリンカ統合の主実装 |
| link.zig | `src/link.zig` | ソース | リンカ共通インターフェース |
| Compilation.zig | `src/Compilation.zig` | ソース | コンパイルパイプライン、リンカ呼び出し |
| codegen/llvm.zig | `src/codegen/llvm.zig` | ソース | LLVMバインディング |
| codegen/llvm/bindings.zig | `src/codegen/llvm/bindings.zig` | ソース | LLVM C API バインディング |
| target.zig | `src/target.zig` | ソース | ターゲットアーキテクチャ情報 |
