# 機能設計書 20-objcopy

## 概要

本ドキュメントは、Zigコンパイラに組み込まれたドロップインobjcopy機能の設計仕様を記載する。`zig objcopy`コマンドは、ZigをGNU binutils付属の`objcopy`互換ツールとして使用するためのインターフェースを提供する。

### 本機能の処理概要

**業務上の目的・背景**：objcopyはオブジェクトファイルのフォーマット変換、セクション操作、デバッグ情報の削除などを行うツールである。組み込みシステム開発では、ELFファイルからフラッシュ書き込み用のバイナリ（.bin）やIntel HEX形式への変換が頻繁に必要となる。本機能により、Zigのみでこれらの変換操作が可能になる。

**機能の利用シーン**：
- ELFファイルからRAWバイナリ（.bin）への変換
- ELFファイルからIntel HEX形式への変換
- デバッグ情報の削除（strip）
- 特定セクションの抽出
- デバッグシンボルの分離（.gnu_debuglink）
- セクションの追加・変更

**主要な処理内容**：
1. コマンドライン引数の解析（objcopy互換）
2. 入力ファイル（ELF）の読み込み
3. 指定された操作の実行
4. 出力フォーマットへの変換
5. ファイル出力

**関連システム・外部連携**：
- Zig標準ライブラリ（ELFパーサー）
- 組み込みシステム開発ツールチェーン

**権限による制御**：特に権限制御は実装されていない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | Objcopyツール画面 | 主機能 | ドロップインobjcopyとしてのオブジェクトファイル変換処理 |

## 機能種別

ファイル変換処理 / ドロップイン互換ツール

## 入力仕様

### 入力パラメータ

objcopy互換の引数をサポート。

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | []const u8 | Yes | 入力ファイル | ELFファイル |
| output | []const u8 | Yes | 出力ファイル | - |
| -O, --output-target | enum | No | 出力フォーマット | binary/elf/hex等 |
| -j, --only-section | []const u8 | No | 指定セクションのみ出力 | - |
| --pad-to | u64 | No | 最終セクションを指定アドレスまでパディング | - |
| -g, --strip-debug | フラグ | No | デバッグセクション削除 | - |
| -S, --strip-all | フラグ | No | 全デバッグセクションとシンボルテーブル削除 | - |
| --only-keep-debug | フラグ | No | デバッグセクションのみ保持 | - |
| --add-gnu-debuglink | []const u8 | No | .gnu_debuglinkセクション追加 | - |
| --extract-to | []const u8 | No | 削除されたセクションを別ファイルに抽出 | - |
| --compress-debug-sections | フラグ | No | DWARFデバッグセクションをzlib圧縮 | - |
| --set-section-alignment | []const u8 | No | セクションアライメント設定 | - |
| --set-section-flags | []const u8 | No | セクションフラグ設定 | - |
| --add-section | []const u8 | No | 新しいセクションを追加 | - |
| -h, --help | フラグ | No | ヘルプ表示 | - |

### 出力フォーマット

| フォーマット | 説明 |
|-------------|------|
| binary | RAWバイナリ（.bin） |
| elf | ELF形式 |
| hex / ihex | Intel HEX形式 |

### 入力データソース

- ELF形式オブジェクトファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| output_file | バイナリ | 変換後のファイル |
| debug_file | バイナリ | 分離されたデバッグ情報（--extract-to時） |

### 出力先

- ファイルシステム（出力引数で指定されたパス）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ オプションと入出力ファイルの取得
2. 入力ファイル読み込み
   └─ ELFヘッダー解析
   └─ セクション/プログラムヘッダー解析
3. 出力フォーマット決定
   └─ -O指定または拡張子から推論
4. 操作実行
   └─ セクション選択/除外
   └─ ストリップ処理
   └─ セクション追加/変更
5. 出力
   └─ 指定フォーマットで書き出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C[ELFファイル読込]
    C --> D{出力フォーマット}
    D -->|binary| E[RAWバイナリ変換]
    D -->|hex| F[Intel HEX変換]
    D -->|elf| G[ELF操作]
    E --> H[セクション処理]
    F --> H
    G --> H
    H --> I{ストリップ?}
    I -->|Yes| J[デバッグ情報削除]
    I -->|No| K[ファイル出力]
    J --> K
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | objcopy互換 | GNU objcopyと同等のインターフェース | 全実行 |
| BR-02 | フォーマット推論 | 出力拡張子（.hex, .bin, .elf）からフォーマットを推論 | -O未指定時 |
| BR-03 | ネイティブエンディアン | ELF to ELF変換はネイティブエンディアンのみサポート | ELF出力時 |
| BR-04 | プログラムヘッダー必須 | ELF to ELF変換はプログラムヘッダー必須 | ELF出力時 |

### セクションフラグ

| フラグ名 | 説明 |
|---------|------|
| alloc | メモリに割り当て |
| contents | 内容あり |
| load | ロード対象 |
| noload | ロードしない |
| readonly | 読み取り専用 |
| code | コードセクション |
| data | データセクション |
| rom | ROMに配置 |
| exclude | 除外 |
| shared | 共有 |
| debug | デバッグ情報 |

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 引数エラー | 入力/出力ファイル未指定 | 使用方法を表示して終了 |
| - | ファイルエラー | 入力ファイルが見つからない | エラーメッセージを出力 |
| - | フォーマットエラー | 無効なELFファイル | エラーメッセージを出力 |
| - | 非サポートエラー | サポートされていない変換 | エラーメッセージを出力 |
| - | エンディアンエラー | 非ネイティブエンディアンのELF | エラーメッセージを出力 |

### リトライ仕様

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

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

本機能はトランザクション処理を必要としない。

## パフォーマンス要件

- 大規模なELFファイルに対応
- ストリーミング処理で効率的な変換

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

- 入力ファイルは信頼されたソースからのものであることが前提
- 出力ファイルのパーミッションは入力ファイルに依存（ELF以外または--only-keep-debug時はデフォルト）

## 備考

- `zig objcopy`はZig言語で実装されており、LLVMに依存しない
- 組み込み開発でよく使用されるELF→binary/hex変換に特化
- ELF to ELF変換は制限あり

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | objcopy.zig | `lib/compiler/objcopy.zig` | **268-275行目**: EmitRawElfOptions構造体。変換オプションを定義 |
| 1-2 | objcopy.zig | `lib/compiler/objcopy.zig` | **357-372行目**: BinaryElfSection構造体。ELFセクション情報 |
| 1-3 | objcopy.zig | `lib/compiler/objcopy.zig` | **365-372行目**: BinaryElfSegment構造体。ELFセグメント情報 |
| 1-4 | objcopy.zig | `lib/compiler/objcopy.zig` | **715-730行目**: SectionFlags構造体。セクションフラグ定義 |

**読解のコツ**: objcopyはELFファイルのセクションとセグメントを解析し、必要な部分のみを抽出して出力フォーマットに変換する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.zig | `src/main.zig` | **321-325行目**: `zig objcopy`コマンドのディスパッチ。jitCmdでobjcopy.zigを呼び出し |
| 2-2 | objcopy.zig | `lib/compiler/objcopy.zig` | **20-244行目**: main関数とcmdObjCopy関数 |

**主要処理フロー**:
1. **26-141行目**: コマンドライン引数解析ループ
2. **145-148行目**: 入力ファイルオープンとstat取得
3. **150-155行目**: ELFヘッダー読み込み
4. **159-169行目**: 出力フォーマット決定（-O指定または拡張子推論）
5. **178-210行目**: フォーマット別の変換処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | objcopy.zig | `lib/compiler/objcopy.zig` | **292-355行目**: emitElf関数。ELF→RAW/HEX変換のメイン処理 |
| 3-2 | objcopy.zig | `lib/compiler/objcopy.zig` | **374-522行目**: BinaryElfOutput.parse関数。ELF解析 |
| 3-3 | objcopy.zig | `lib/compiler/objcopy.zig` | **529-657行目**: HexWriter構造体。Intel HEX出力 |

**主要処理フロー**:
- **299行目**: BinaryElfOutput.parseでELFを解析
- **306-327行目**: --only-section指定時の処理
- **329-354行目**: フォーマット別出力（raw/hex）

#### Step 4: Intel HEX出力を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | objcopy.zig | `lib/compiler/objcopy.zig` | **529-657行目**: HexWriter構造体とRecord構造体 |

**主要処理フロー**:
- **543-548行目**: Record.Type enum（Data, EOF, ExtendedSegmentAddress, ExtendedLinearAddress）
- **610-626行目**: Record.write関数。HEXレコードの書き出し
- **629-643行目**: writeSegment関数。セグメントをHEXに変換

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

```
main.zig::mainArgs
    │
    └─ jitCmd (objcopy.zig)
           │
           └─ objcopy.zig::main
                  │
                  └─ cmdObjCopy
                         │
                         ├─ 引数解析 (26-141行目)
                         │
                         ├─ ELFヘッダー読込 (150-155行目)
                         │
                         └─ emitElf
                                │
                                ├─ BinaryElfOutput.parse
                                │      │
                                │      ├─ セクションヘッダー解析
                                │      └─ プログラムヘッダー解析
                                │
                                ├─ writeBinaryElfSection (RAW出力)
                                │
                                └─ HexWriter.writeSegment (HEX出力)
```

### データフロー図

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

ELFファイル ───▶ ELFヘッダー読込 ───▶ ヘッダー情報
                       │
                       ▼
              BinaryElfOutput.parse
                       │
                       ▼
              セクション/セグメント情報
                       │
           ┌───────────┼───────────┐
           │           │           │
           ▼           ▼           ▼
      RAW出力      HEX出力      ELF操作
           │           │           │
           ▼           ▼           ▼
      .binファイル  .hexファイル  .elfファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.zig | `src/main.zig` | ソース | CLIエントリーポイント |
| objcopy.zig | `lib/compiler/objcopy.zig` | ソース | objcopy実装（Zig） |
| elf.zig | `lib/std/elf.zig` | ソース | ELF形式定義・パーサー |
