# 機能設計書 37-ELFリンカ

## 概要

本ドキュメントは、ZigコンパイラにおけるELF（Executable and Linkable Format）形式のリンカ機能の設計を記述する。

### 本機能の処理概要

ELFリンカは、コンパイラが生成したオブジェクトファイルや外部ライブラリを結合し、Linux等のUnix系OS向けの実行可能ファイルや共有ライブラリを生成する機能を提供する。Zigはネイティブのリンカを実装しており、GNU ldやLLVM lldに依存せずにリンク処理を実行できる。

**業務上の目的・背景**：ELFはLinux、BSD、多くのUnix系OSで使用される標準的なバイナリ形式である。Zigがネイティブでリンカを実装することで、(1) 外部リンカへの依存を排除し、(2) クロスコンパイル時のリンカ互換性問題を解消し、(3) インクリメンタルコンパイルをサポートし、(4) より高速なリンク処理を実現できる。

**機能の利用シーン**：
- Linux向け実行可能ファイル（ELF executable）の生成
- Linux向け共有ライブラリ（.so）の生成
- 静的ライブラリ（.a）の生成
- 他のUnix系OS（FreeBSD、OpenBSD等）向けバイナリの生成
- 組み込みLinux環境向けファームウェアの生成

**主要な処理内容**：
1. 入力ファイル（オブジェクト、アーカイブ、共有ライブラリ）の解析
2. シンボル解決とリロケーション処理
3. セクションとセグメントの配置
4. プログラムヘッダーとセクションヘッダーの生成
5. 動的リンク情報（.dynamic、.dynsym等）の生成
6. PLT/GOTの構築
7. ハッシュテーブル（.hash、.gnu.hash）の生成
8. TLS（Thread Local Storage）サポート

**関連システム・外部連携**：コードジェネレータ（aarch64、riscv64、x86_64等）から生成されたマシンコードを受け取り、最終的なバイナリを出力する。

**権限による制御**：特になし（コンパイル時の処理）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 実行ファイルビルド画面 | 遷移先機能 | ELF形式の実行可能ファイルのリンク処理（Linux） |

## 機能種別

リンク処理 / バイナリ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| comp | *Compilation | Yes | コンパイル単位 | 有効なCompilationであること |
| emit | Path | Yes | 出力パス | 有効なパスであること |
| options | OpenOptions | Yes | リンクオプション | 有効なオプションであること |

### 入力データソース

- Zigコンパイラが生成したZigObject
- 外部オブジェクトファイル（.o）
- 静的ライブラリ（.a）
- 共有ライブラリ（.so）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| file | File.Handle | 出力ファイルハンドル |
| phdrs | ProgramHeaderList | プログラムヘッダー |
| sections | MultiArrayList(Section) | セクション情報 |
| symtab | ArrayList(elf.Elf64_Sym) | シンボルテーブル |
| strtab | ArrayList(u8) | 文字列テーブル |

### 出力先

ELF実行可能ファイルまたは共有ライブラリ

## 処理フロー

### 処理シーケンス

```
1. 初期化フェーズ
   └─ ファイル作成、ヘッダー構造初期化
2. 入力ファイル解析
   └─ オブジェクト、アーカイブ、共有ライブラリの読み込み
3. シンボル解決
   └─ グローバルシンボルの解決、未定義シンボルの検出
4. セクション配置
   └─ アドレス割り当て、アライメント調整
5. リロケーション処理
   └─ 相対/絶対アドレスの解決
6. 動的リンク情報生成
   └─ .dynamic、.dynsym、.dynstr等の生成
7. PLT/GOT構築
   └─ プロシージャリンケージテーブル、グローバルオフセットテーブル
8. 出力
   └─ ELFファイルの書き出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始: 入力ファイル] --> B[初期化]
    B --> C[入力ファイル解析]
    C --> D[シンボル解決]
    D --> E{未定義シンボル?}
    E -->|Yes| F[エラー報告]
    E -->|No| G[セクション配置]
    G --> H[リロケーション処理]
    H --> I[動的リンク情報生成]
    I --> J[PLT/GOT構築]
    J --> K[ELFファイル出力]
    K --> L[終了]
    F --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-1 | ページアライメント | セグメントはページ境界に配置 | セグメント配置時 |
| BR-37-2 | シンボルバージョニング | .verneed/.versymでバージョン管理 | 動的リンク時 |
| BR-37-3 | GCセクション | 未使用セクションの削除 | gc_sectionsオプション有効時 |

### 計算ロジック

- ページサイズ: アーキテクチャ依存（4KB〜1MB）
- イメージベース: PIC無効時は固定アドレス、PIE/共有ライブラリは0

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

該当なし（データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| undefined symbol | リンクエラー | 未定義シンボル | シンボル名を報告 |
| duplicate symbol | リンクエラー | 重複シンボル | 両方の定義箇所を報告 |
| relocation overflow | リンクエラー | アドレス範囲外 | サンクを挿入 |

### リトライ仕様

リトライ機構は実装されていない

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

該当なし

## パフォーマンス要件

- インクリメンタルリンク対応
- 最小テキスト容量: 64バイト + 予約容量

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

- RELRO（Read-Only Relocations）サポート
- PIE（Position Independent Executable）サポート
- スタックサイズ設定（PT_GNU_STACK）

## 備考

Elf2.zigは次世代実装で、並列処理対応を含む。

---

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

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

### 推奨読解順序

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

まず、ELFリンカの主要データ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Elf.zig | `src/link/Elf.zig` | 主要フィールド定義 |

**読解のコツ**: ELF構造はプログラムヘッダー（実行時）とセクションヘッダー（リンク時）の二重構造を持つ。phdrsとsectionsの両方を理解する必要がある。

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

リンカの初期化と主要機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Elf.zig | `src/link/Elf.zig` | createEmpty関数（193行目以降） |

**主要処理フロー**:
1. **1-100行目**: 主要フィールド定義（files、sections、phdrs等）
2. **105-128行目**: SectionIndexes構造体
3. **130-180行目**: ProgramHeaderIndexes構造体
4. **193-300行目**: createEmpty関数（初期化処理）

#### Step 3: セクションとセグメント管理を理解する

ELF固有のセクション/セグメント管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Elf.zig | `src/link/Elf.zig` | Section構造体、phdr_indexes/section_indexes |

**主要処理フロー**:
- 動的セクション: .dynamic、.dynsym、.dynstr
- GOT/PLT: got、plt、got_plt、plt_got
- リロケーション: rela_dyn、rela_plt

#### Step 4: Atomを理解する

リンク単位であるAtomを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Elf/Atom.zig | `src/link/Elf/Atom.zig` | Atom構造体 |

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

```
link.zig (リンカエントリ)
    │
    ├─ Elf.zig
    │      ├─ createEmpty() - 初期化
    │      ├─ open() - ファイルオープン
    │      ├─ flush() - 書き出し
    │      │
    │      ├─ files管理
    │      │      ├─ ZigObject
    │      │      ├─ Object
    │      │      └─ SharedObject
    │      │
    │      ├─ sections管理
    │      │      ├─ symtab
    │      │      ├─ strtab
    │      │      ├─ dynsym
    │      │      └─ dynamic
    │      │
    │      ├─ phdrs管理
    │      │      ├─ PT_LOAD
    │      │      ├─ PT_DYNAMIC
    │      │      └─ PT_GNU_STACK
    │      │
    │      └─ セクション管理
    │             ├─ got
    │             ├─ plt
    │             ├─ rela_dyn
    │             └─ rela_plt
    │
    └─ Elf/Atom.zig
           └─ Atom構造体
```

### データフロー図

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

ZigObject ───┐
             │
Object   ────┼──▶ シンボル解決 ───▶ セクション配置 ───▶ ELFファイル
             │         │                   │
SharedObj ───┘         ▼                   ▼
                  リロケーション        PLT/GOT生成
                       │                   │
                       ▼                   ▼
                  アドレス解決 ◀─────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Elf.zig | `src/link/Elf.zig` | ソース | メインELFリンカロジック |
| Elf2.zig | `src/link/Elf2.zig` | ソース | 次世代ELFリンカ（並列対応） |
| Elf/Atom.zig | `src/link/Elf/Atom.zig` | ソース | リンク単位Atom |
