# 機能設計書 97-llvm-strings

## 概要

本ドキュメントは、LLVMプロジェクトにおけるllvm-strings（文字列検索ツール）の機能設計書である。llvm-stringsは、バイナリファイルから印刷可能な文字列を検索・表示するツールであり、GNU binutilsのstringsコマンドと互換性がある。

### 本機能の処理概要

llvm-stringsは、バイナリファイル、オブジェクトファイル、アーカイブファイルを読み込み、連続した印刷可能文字の列（文字列）を検出して表示するツールである。

**業務上の目的・背景**：バイナリファイル内にハードコードされた文字列（エラーメッセージ、設定値、デバッグ情報等）を調査する必要がある場面で使用される。リバースエンジニアリング、マルウェア解析、デバッグなどで広く活用される。

**機能の利用シーン**：
- バイナリファイル内の埋め込み文字列の調査
- マルウェア解析での文字列抽出
- デバッグ情報の確認
- バイナリ内のハードコード値の検出

**主要な処理内容**：
1. ファイルの読み込み
2. 印刷可能文字の連続検出
3. 最小文字数フィルタリング
4. オフセット情報の付加（オプション）
5. 結果の出力

**関連システム・外部連携**：特になし（スタンドアロンツール）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | コマンドライン | 主画面 | コマンドライン引数による操作 |

## 機能種別

テキスト抽出 / バイナリ解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input files | string[] | No | 入力ファイル（デフォルト: 標準入力） | - |
| -n, --bytes | int | No | 最小文字列長（デフォルト: 4） | 正の整数 |
| -f, --print-file-name | bool | No | ファイル名を表示 | - |
| -t, --radix | char | No | オフセット表示形式（o/d/x） | o/d/x/空 |

### 入力データソース

- バイナリファイル
- オブジェクトファイル
- アーカイブファイル
- 標準入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ファイル名 | text | 入力ファイル名（-fオプション時） |
| オフセット | text | 文字列のファイル内位置（-tオプション時） |
| 文字列 | text | 検出された印刷可能文字列 |

### 出力先

標準出力（stdout）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン解析
   └─ オプションと入力ファイルの取得
2. 各ファイルの処理
   └─ MemoryBuffer::getFileOrSTDIN()
3. 文字列検出
   └─ strings()関数で印刷可能文字列抽出
4. 結果出力
   └─ print()ラムダで整形出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C{入力ファイル指定?}
    C -->|No| D[標準入力を使用]
    C -->|Yes| E[ファイルリスト取得]
    D --> F[ファイルループ]
    E --> F
    F --> G[MemoryBuffer::getFileOrSTDIN]
    G --> H{読込成功?}
    H -->|No| I[エラー出力]
    H -->|Yes| J[strings関数呼出]
    I --> K{次のファイル?}
    J --> K
    K -->|Yes| F
    K -->|No| L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-97-01 | 印刷可能判定 | isPrint()またはタブ文字を印刷可能とする | 文字判定時 |
| BR-97-02 | 最小長フィルタ | MinLength未満の文字列は出力しない | 文字列出力時 |
| BR-97-03 | 標準入力表示 | 標準入力は"{standard input}"と表示 | -fオプション時 |
| BR-97-04 | オフセット形式 | o=8進数、d=10進数、x=16進数 | -tオプション時 |

### 計算ロジック

- オフセット計算: 文字列開始位置 - バッファ先頭

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

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

本ツールはデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | 無効なオプション値 | 有効な値を使用 |
| EXIT_FAILURE | 最小長エラー | --bytes=0 | 正の整数を指定 |
| (警告) | ファイルエラー | ファイル読込失敗 | パス確認（処理継続） |

### リトライ仕様

リトライは実装されていない。ファイル読込失敗時は警告を出力して次のファイルへ進む。

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

該当なし

## パフォーマンス要件

- ファイルサイズに比例した処理時間
- メモリマップドファイルI/Oを使用

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

- バイナリファイルの内容をそのまま出力するため、端末エスケープシーケンス等に注意

## 備考

GNU stringsとの互換性を意識した設計。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | llvm-strings.cpp | `llvm/tools/llvm-strings/llvm-strings.cpp` | radix列挙型、グローバル変数 |

**読解のコツ**: radix列挙型がオフセット表示形式を定義し、MinLength/PrintFileName/Radixがグローバル設定。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-strings.cpp | `llvm/tools/llvm-strings/llvm-strings.cpp` | main関数 |

**主要処理フロー**:
1. **128-136行目**: 初期化とコマンドライン解析
2. **152-153行目**: 最小長チェック
3. **172-173行目**: 入力ファイルなしの場合標準入力を使用
4. **176-184行目**: 各ファイルの処理ループ

#### Step 3: 文字列検出を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-strings.cpp | `llvm/tools/llvm-strings/llvm-strings.cpp` | strings関数 |

**主要処理フロー**:
- **91-126行目**: strings()関数全体
- **92-111行目**: print()ラムダ - 出力フォーマット処理
- **113-126行目**: 文字列検出ループ

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

```
main() [llvm-strings.cpp:128]
    │
    ├─ Tbl.parseArgs() [134行目]
    │
    ├─ parseIntArg() [152行目]
    │      └─ MinLength設定
    │
    └─ [ファイルループ] [176行目]
           │
           ├─ MemoryBuffer::getFileOrSTDIN()
           │
           └─ strings() [91行目]
                  │
                  ├─ [文字ループ]
                  │      │
                  │      ├─ isPrint() / タブ判定
                  │      │
                  │      └─ 印刷可能なら文字列に追加
                  │
                  └─ print() [ラムダ]
                         │
                         ├─ ファイル名出力 (-f)
                         ├─ オフセット出力 (-t)
                         └─ 文字列出力
```

### データフロー図

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

バイナリファイル ──────▶ MemoryBuffer ──────▶ バイト列
                              │
                              ▼
                        文字ループ
                              │
                              ├─ isPrint()? ──▶ 印刷可能
                              │
                              └─ タブ? ───────▶ 印刷可能
                              │
                              ▼
                        文字列蓄積
                              │
                              ▼
                        MinLength判定
                              │
                              ▼
                        print() ──────────▶ 標準出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-strings.cpp | `llvm/tools/llvm-strings/llvm-strings.cpp` | ソース | 全機能の実装 |
| Opts.inc | `llvm/tools/llvm-strings/Opts.inc` | 生成ファイル | コマンドラインオプション定義 |
