# API設計書

## 概要

本ドキュメントは、LLVM プロジェクトが提供する HTTP API インターフェースについて記載します。LLVM プロジェクトは主にコンパイラ基盤であり、従来のWebアプリケーションとは異なりますが、**llvm-debuginfod** コンポーネントが debuginfod プロトコルに準拠した HTTP API を提供しています。

debuginfod は、デバッグ情報（DWARF）、実行ファイル、ソースコードを Build ID に基づいて配信するための標準プロトコルです。

## 共通仕様

### ベースURL

```
http://{host}:{port}
```

デフォルトでは、サーバーは `0.0.0.0` の任意のポートでリッスンします。ポートは `--port` オプションで指定可能です。

### 認証方式

認証なし（オープンアクセス）

ただし、環境変数 `DEBUGINFOD_HEADERS_FILE` で指定したファイルからカスタムHTTPヘッダーを追加することが可能です。

### 共通ヘッダー

| ヘッダー名 | 必須 | 説明 |
| --- | --- | --- |
| Content-Type | - | レスポンス: `application/octet-stream` (バイナリファイル) または `text/plain` (エラーメッセージ) |

### 共通エラーレスポンス

| ステータスコード | 説明 |
| --- | --- |
| 404 | Not Found - 指定された Build ID に対応するアーティファクトが見つからない |

## API一覧

| カテゴリ | エンドポイント | メソッド | 説明 |
| --- | --- | --- | --- |
| デバッグ情報 | /buildid/{build_id}/debuginfo | GET | 指定された Build ID のデバッグ情報バイナリを取得 |
| 実行ファイル | /buildid/{build_id}/executable | GET | 指定された Build ID の実行ファイルを取得 |
| ソースコード | /buildid/{build_id}/source/{path} | GET | 指定された Build ID のソースファイルを取得（クライアント側でサポート） |

## 各APIエンドポイント定義

### デバッグ情報取得

#### 1. デバッグ情報バイナリ取得

指定された Build ID に対応するデバッグ情報（DWARF）を含むバイナリファイルを取得します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /buildid/{build_id}/debuginfo` |
| 認証 | 不要 |
| 権限 | なし |

**パスパラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| build_id | string | ○ | ELFバイナリの Build ID（16進数文字列、小文字） |

**クエリパラメータ**

なし

**リクエストボディ**

なし

**レスポンス（成功時）**

ステータスコード: `200 OK`

Content-Type: `application/octet-stream`

レスポンスボディ: デバッグ情報を含むELFバイナリファイル（ストリーミング転送）

**レスポンス（エラー時）**

ステータスコード: `404 Not Found`

Content-Type: `text/plain`

```
Build ID not found
```

または

```
Build ID is not a hex string
```

---

### 実行ファイル取得

#### 2. 実行ファイル取得

指定された Build ID に対応する実行ファイル（strip済みまたは未strip）を取得します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /buildid/{build_id}/executable` |
| 認証 | 不要 |
| 権限 | なし |

**パスパラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| build_id | string | ○ | ELFバイナリの Build ID（16進数文字列、小文字） |

**クエリパラメータ**

なし

**リクエストボディ**

なし

**レスポンス（成功時）**

ステータスコード: `200 OK`

Content-Type: `application/octet-stream`

レスポンスボディ: 実行ファイル（ELFバイナリ、ストリーミング転送）

**レスポンス（エラー時）**

ステータスコード: `404 Not Found`

Content-Type: `text/plain`

```
Build ID not found
```

または

```
Build ID is not a hex string
```

---

### ソースコード取得（クライアント側実装）

#### 3. ソースファイル取得

指定された Build ID に対応するソースファイルを取得します。

**注意**: 現時点では llvm-debuginfod サーバーはソースファイルの提供をサポートしていませんが、クライアント側 (`llvm-debuginfod-find`) ではこのエンドポイントへのリクエストがサポートされています。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| エンドポイント | `GET /buildid/{build_id}/source/{source_path}` |
| 認証 | 不要 |
| 権限 | なし |

**パスパラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| build_id | string | ○ | ELFバイナリの Build ID（16進数文字列、小文字） |
| source_path | string | ○ | ソースファイルの絶対パス（POSIXスタイル、スラッシュ区切り） |

**クエリパラメータ**

なし

**リクエストボディ**

なし

**レスポンス（成功時）**

ステータスコード: `200 OK`

Content-Type: `application/octet-stream`

レスポンスボディ: ソースファイルの内容

**レスポンス（エラー時）**

ステータスコード: `404 Not Found`

---

## サーバー設定オプション

llvm-debuginfod サーバーの起動時に指定可能なオプション:

| オプション | 説明 | デフォルト値 |
| --- | --- | --- |
| `--port` | リッスンするポート番号 | 0（自動割り当て） |
| `--host-interface` | バインドするホストインターフェース | 0.0.0.0 |
| `--scan-interval` | ディレクトリスキャン間隔（秒） | 300 |
| `--min-interval` | オンデマンド更新の最小間隔（秒） | 10.0 |
| `--max-concurrency` | 最大並列数 | 0（自動） |
| `-v, --verbose-logging` | 詳細ログを出力 | false |

## クライアント設定（環境変数）

| 環境変数 | 説明 | デフォルト値 |
| --- | --- | --- |
| `DEBUGINFOD_URLS` | debuginfod サーバーURLのスペース区切りリスト | なし |
| `DEBUGINFOD_CACHE_PATH` | ローカルキャッシュディレクトリのパス | システムキャッシュディレクトリ |
| `DEBUGINFOD_TIMEOUT` | HTTPリクエストのタイムアウト（秒） | 90 |
| `DEBUGINFOD_HEADERS_FILE` | カスタムHTTPヘッダーを含むファイルのパス | なし |
| `DEBUGINFOD_CACHE_POLICY` | キャッシュ削除ポリシー | なし |

## Build ID について

Build ID は ELF バイナリに埋め込まれた一意の識別子です。通常、以下の方法で取得できます:

```bash
# readelfを使用
readelf -n <binary> | grep "Build ID"

# llvm-readelfを使用
llvm-readelf -n <binary> | grep "Build ID"

# 出力例: Build ID: 2c39b7557c50162aaeb5a3148c9f76e6e46012e3
```

## 使用例

### サーバーの起動

```bash
# 指定ディレクトリをスキャンしてサーバーを起動
llvm-debuginfod -v /path/to/binaries

# 特定のポートで起動
llvm-debuginfod --port 8080 /path/to/binaries
```

### クライアントからの取得

```bash
# 環境変数を設定
export DEBUGINFOD_URLS="http://localhost:8080"
export DEBUGINFOD_CACHE_PATH=/tmp/debuginfod-cache

# デバッグ情報を取得
llvm-debuginfod-find --debuginfo 2c39b7557c50162aaeb5a3148c9f76e6e46012e3

# 実行ファイルを取得
llvm-debuginfod-find --executable 2c39b7557c50162aaeb5a3148c9f76e6e46012e3

# 取得したファイルの内容をダンプ
llvm-debuginfod-find --dump --debuginfo 2c39b7557c50162aaeb5a3148c9f76e6e46012e3
```

### curl を使用した直接リクエスト

```bash
# デバッグ情報の取得
curl -o debug.elf http://localhost:8080/buildid/2c39b7557c50162aaeb5a3148c9f76e6e46012e3/debuginfo

# 実行ファイルの取得
curl -o executable http://localhost:8080/buildid/2c39b7557c50162aaeb5a3148c9f76e6e46012e3/executable
```

## 備考

- llvm-debuginfod は `LLVM_ENABLE_HTTPLIB` フラグを有効にしてビルドする必要があります
- HTTP クライアント機能には `LLVM_ENABLE_CURL` フラグも必要です
- 現在、ソースファイルの提供はサーバー側では未実装です
- フェデレーション機能により、ローカルに見つからない Build ID は `DEBUGINFOD_URLS` で指定された他のサーバーに問い合わせます
- ファイルはストリーミング転送されるため、大きなバイナリでもメモリ効率が良好です
