青木峰郎『ふつうのコンパイラをつくろう』の目次がやばいのでサイン会@RubyKaigiのお知らせ

(7/22追記:ふつパイラのサポートページができていました。下記よりもサポートページの方が確実かと思うので、そちらをどうぞ。)

青木峰郎先生が3年の歳月を費やしてついに完成させた労作『ふつうのコンパイラをつくろう』、RubyKaigi2009で先行発売されているのはみなさんご存知というか、もちろん来場されたみなさんはすでに購入済みかと思うのですが、買いそびれてしまった方のために、とある信頼できる情報筋から目次のデータをゲットいたしました。以下に転載いたします。

中身についてはあえて多くは語りませんが、構文解析からアセンブラ生成と最適化を終えて、その後に「第4部 リンクとロード」があるのが注目だそうです。ELFの話から位置独立コードの話まで、「そこまでやるか」もきっちりフォローするのが青木先生の「ふつう」の「ふつう」たるところと言えましょう。読んでないけど。

そして明日は12:00からRubykaigi2009会場にて、青木先生と江渡先生の合同サイン会も開催されますので、RubyKaigiに参加されているラッキーな方は、ぜひ購入して、ついでにサインもゲットされることをおすすめします。

ちなみに同じく明日のRubyKaigiでは、15:30からまつもとゆきひろ先生とyhara先生の合同サイン会も開催されます。こちらもぜひご参加ください。

『ふつうのコンパイラを作ろう』目次

 ふつうのまえがき ---- iii
 前提となる知識 ---- v
 前提としない知識 ---- v
 本書の構成 ---- vi
 謝辞 ---- vii

第 1 章  コンパイラ作りを始めよう 1

1.1  本書の概要 ---- 2

 本書のテーマ ---- 2
 本書で作成するコンパイラ ---- 2
 コンパイルの例 ---- 3
 実行可能ファイルとは ---- 4
 コンパイルとは ---- 5
 プログラム実行環境 ---- 8

1.2  コンパイルの過程 ---- 11

 コンパイルの4 つの段階 ---- 11
 構文解析 ---- 11
 意味解析 ---- 12
 中間表現の生成 ---- 13
 コード生成 ---- 14
 最適化 ---- 14
 まとめ ---- 15

1.3  C♭コンパイラによるコンパイル ---- 16
 C♭コンパイラの必要環境 ---- 16
 C♭コンパイラのインストール ---- 17
 C♭によるHello, World! ---- 17

第 2 章  C♭とcbc 19

2.1  C♭言語の概要 ---- 20
 C♭でのHello, World! ---- 20
 C♭で削除された機能 ---- 21
 import 宣言の仕様 ---- 22
 インポートファイルの仕様 ---- 23

2.2  C♭コンパイラcbc の構成 ---- 25
 cbc のソースツリー ---- 25
 cbc のパッケージ ---- 26
 compiler パッケージのクラス群 ---- 27
 main メソッドの実装 ---- 27
 commandMain メソッドの実装 ---- 28
 Java 5 のgenerics ---- 29
 build メソッドの実装 ---- 29
 Java 5 のforeach 文 ---- 30
 compile メソッドの実装 ---- 31

第1 部 ソースコードの解析

第 3 章  構文解析の概要 35

3.1  構文解析の手法 ---- 36
 ソースコード解析の問題点 ---- 36
 ソースコード解析の定石 ---- 36
 字句解析、構文解析、意味解析 ---- 37
 スキャナの働き ---- 38
 単語の種類と意味値 ---- 39
 トークン ---- 40
 抽象構文木とノード ---- 41

3.2  パーサジェネレータ ---- 43
 パーサジェネレータとは ---- 43
 パーサジェネレータの種類 ---- 43
 パーサジェネレータの選択 ---- 44

3.3  JavaCC の概要 ---- 47
 JavaCC とは ---- 47
 文法記述ファイル ---- 47
 文法記述ファイルの例 ---- 48
 JavaCC の実行 ---- 50
 JavaCC で生成したパーサの起動 ---- 51
 日本語の処理 ---- 53

第 4 章  字句解析 55

4.1  JavaCC によるスキャナの記述 ---- 56
 この章の目的 ---- 56
 JavaCC の正規表現 ---- 56
 固定文字列 ---- 57
 連接 ---- 57
 文字クラス ---- 58
 否定文字クラス ---- 58
 1 回以上の繰り返し ---- 59
 0 回以上の繰り返し ---- 59
 n 回からm 回の繰り返し ---- 60
 ちょうどn 回の繰り返し ---- 60
 省略可能 ---- 61
 選択 ---- 61

4.2  構造のない単語のスキャン ---- 63
 TOKEN 命令 ---- 63
 識別子と予約語のスキャン ---- 63
 マッチする規則の選択 ---- 65
 数値のスキャン ---- 66

4.3  トークンを生成しない単語のスキャン ---- 68
 SKIP 命令とSPECIAL_TOKEN 命令 ---- 68
 空白の読み捨て ---- 69
 行コメントの読み捨て ---- 69

4.4  構造を持つ単語のスキャン ---- 71
 最長一致の原則とその問題 ---- 71
 状態遷移を使ったスキャン ---- 72
 MORE 命令 ---- 73
 ブロックコメントの読み捨て ---- 75
 文字列リテラルのスキャン ---- 76
 文字リテラルのスキャン ---- 76

第 5 章  JavaCC によるパーサの記述 79

5.1  EBNF による文法の記述 ---- 80
 この章の目的 ---- 80
 JavaCC での文法の記述 ---- 81
 終端記号と非終端記号 ---- 82
 JavaCC のEBNF 記法 ---- 83
 連接 ---- 84
 0 回以上の繰り返し ---- 84
 1 回以上の繰り返し ---- 85
 選択 ---- 86
 省略可能 ---- 86

5.2  曖昧な文法とトークンの先読み ---- 87
 曖昧な文法 ---- 87
 JavaCC の制限 ---- 89
 左端共通部分のくくり出し ---- 89
 トークンの先読み ---- 90
 省略可能な規則と衝突 ---- 92
 繰り返しと衝突 ---- 93
 より柔軟なトークンの先読み ---- 94
 先読みに関する注意 ---- 95

第 6 章  構文解析 97

6.1  定義の解析 ---- 98
 プログラム全体を表す記号 ---- 98
 構文の単位 ---- 99
 import 宣言の構文 ---- 100
 さまざまな定義の構文 ---- 101
 変数定義の構文 ---- 103
 関数定義の構文 ---- 104
 構造体定義と共用体定義の構文 ---- 106
 構造体メンバと共用体メンバの構文 ---- 107
 typedef 文の構文 ---- 108
 型の構文 ---- 108
 C 言語とC♭の変数定義の違い ---- 109
 基本型の構文 ---- 110

6.2  文の解析 ---- 113
 文の構文 ---- 113
 if 文の構文 ---- 114
 if 文と中括弧の省略 ---- 115
 while 文の構文 ---- 116
 for 文の構文 ---- 116
 さまざまなジャンプ文の構文 ---- 117

6.3  式の解析 ---- 118
 式の全体構造 ---- 118
 expr の規則 ---- 119
 条件式 ---- 120
 二項演算子 ---- 121

6.4  項の解析 ---- 125
 項の規則 ---- 125
 前置演算子の規則 ---- 125
 後置演算子の規則 ---- 126
 リテラルの規則 ---- 127

第2 部 抽象構文木と中間表現

第 7 章  JavaCC のアクションと抽象構文木 131

7.1  JavaCC のアクション ---- 132
 この章の目的 ---- 132
 簡単なアクション ---- 132
 アクションの実行されるタイミング ---- 133
 意味値を返すアクション ---- 135
 終端記号の意味値の取り出し ---- 136
 Token クラスのフィールド ---- 137
 非終端記号の意味値の取り出し ---- 139
 構文木の構築 ---- 140
 選択とアクション ---- 141
 繰り返しとアクション ---- 143
 この節のまとめ ---- 145

7.2  抽象構文木とノード ---- 147
 Node クラス群 ---- 147
 Node クラスの定義 ---- 149
 抽象構文木の表示 ---- 150
 ノードによる式の表現の例 ---- 152

第 8 章  抽象構文木の作成 157

8.1  式の抽象構文木 ---- 158
 リテラルの抽象構文木 ---- 158
 型の表現 ---- 160
 TypeRef クラスが必要な理由 ---- 161
 単項演算の抽象構文木 ---- 162
 二項演算の抽象構文木 ---- 164
 条件式の抽象構文木 ---- 166
 代入式の抽象構文木 ---- 167

8.2  文の抽象構文木 ---- 171
 if 文の抽象構文木 ---- 171
 while 文の抽象構文木 ---- 172
 複文の抽象構文木 ---- 174

8.3  宣言の抽象構文木 ---- 176
 変数宣言リストの抽象構文木 ---- 176
 関数定義の抽象構文木 ---- 178
 宣言リストを表す抽象構文木 ---- 179
 プログラム全体を表す抽象構文木 ---- 180
 外部シンボルのインポート ---- 181
 まとめ ---- 182

8.4  cbc パーサの起動 ---- 185
 Parser オブジェクトの生成 ---- 185
 ファイルのパース ---- 186
 パーサの起動 ---- 188

第 9 章  意味解析(1)参照の解決 189

9.1  意味解析の概要 ---- 190
 この章の目的 ---- 190
 抽象構文木のトラバース ---- 191
 Visitor パターンを使わない抽象構文木の処理 ---- 192
 Visitor パターンによる抽象構文木の処理 ---- 194
 Visitor パターンの一般化 ---- 196
 cbc におけるVisitor パターンの実装 ---- 198
 意味解析に関わるcbc のクラス ---- 199

9.2  変数参照の解決 ---- 201
 問題の概要 ---- 201
 実装の概要 ---- 201
 Scope ツリーの構造 ---- 203
 LocalResolver クラスのフィールド ---- 204
 LocalResolver クラスの起動 ---- 205
 変数定義の登録 ---- 206
 関数定義の処理 ---- 207
 pushScope メソッド ---- 208
 currentScope メソッド ---- 209
 popScope メソッド ---- 209
 ローカルスコープの追加 ---- 210
 VariableNode と変数定義の対応付け ---- 211
 スコープツリーからの変数定義の取得 ---- 212

9.3  型名の解決 ---- 214
 問題の概要 ---- 214
 実装の概要 ---- 214
 TypeResolver クラスのフィールド ---- 214
 TypeResolver クラスの起動 ---- 215
 型の宣言 ---- 216
 型と抽象構文木のトラバース ---- 217
 変数定義の型の解決 ---- 218
 関数定義の型の解決 ---- 219

第 10 章  意味解析(2)静的型チェック 221

10.1  型定義のチェック ---- 222
 問題の概要 ---- 222
 実装の概要 ---- 223
 有向グラフのループを検出するアルゴリズム ---- 225
 構造体・共用体の循環定義チェック ---- 226

10.2  式の妥当性のチェック ---- 229
 問題の概要 ---- 229
 実装の概要 ---- 230
 DereferenceChecker クラスの起動 ---- 231
 例外SemanticError の捕捉 ---- 232
 左辺値でない式のアドレス取得のチェック ---- 233
 ポインタでない値のデリファレンスのチェック ---- 234
 暗黙のポインタ生成 ---- 235

10.3  静的型チェック ---- 237
 問題の概要 ---- 237
 実装の概要 ---- 238
 C♭における演算の型 ---- 238
 暗黙の型変換 ---- 240
 TypeChecker クラスの起動 ---- 241
 二項演算式の型チェック ---- 242
 暗黙の型変換の実装 ---- 244

第 11 章  中間表現への変換 249

11.1  cbc の中間表現 ---- 250
 中間表現の表示 ---- 250
 中間表現を構成するクラス ---- 252
 中間表現ノードのフィールド ---- 253
 中間表現の演算子と型 ---- 254
 さまざまな中間表現 ---- 255
 中間表現の目的 ---- 256

11.2  IRGenerator クラスの概要 ---- 258
 抽象構文木のトラバースと返り値 ---- 258
 IRGenerator クラスの起動 ---- 258
 関数本体の変換 ---- 259
 文である式の判別 ---- 260

11.3  制御構造の変換 ---- 263
 if 文の変換(1)概要 ---- 263
 if 文の変換(2)else 節がない場合 ---- 264
 if 文の変換(3)else 節がある場合 ---- 265
 while 文の変換 ---- 266
 break 文の変換(1)問題の定義 ---- 268
 break 文の変換(2)実装の方針 ---- 269
 break 文の変換(3)実装 ---- 270

11.4  副作用のない式の変換 ---- 273
 UnaryOpNode オブジェクトの変換 ---- 273
 BinaryOpNode オブジェクトの変換 ---- 274
 ポインタに対する加減算の変換 ---- 276

11.5  左辺値の変換 ---- 279
 左辺と右辺 ---- 279
 左辺値と右辺値 ---- 279
 cbc での左辺値の表現 ---- 280
 構造体メンバのオフセット ---- 282
 メンバ参照(expr.memb)の変換 ---- 283
 左辺値変換の例外:配列と関数 ---- 285
 メンバ参照式(ptr->memb)の変換 ---- 286

11.6  副作用を持つ式の変換 ---- 288
 式の副作用とは ---- 288
 副作用を持つ式の変換方針 ---- 289
 単純な代入式の変換(1)文である場合 ---- 290
 テンポラリ変数の導入 ---- 291
 単純な代入式の変換(2)式である場合 ---- 293
 後置インクリメントの変換 ---- 295

第3 部 アセンブリコードの生成

第 12 章  x86 アーキテクチャの概要 301

12.1  コンピュータの仕組み ---- 302
 CPU とメモリ ---- 302
 レジスタ ---- 303
 アドレス ---- 303
 物理アドレスと仮想アドレス ---- 304
 さまざまなデバイス ---- 306
 キャッシュメモリ ---- 308

12.2  x86 系CPU の歴史 ---- 311
 x86 系CPU とは ---- 311
 32 ビットCPU とは ---- 312
 インストラクションセットとは ---- 313
 IA-32 の変遷 ---- 314
 IA-32 の64 ビット拡張 〜 AMD64 〜 ---- 315

12.3  IA-32 の概要 ---- 317
 IA-32 のレジスタ ---- 317
 汎用レジスタ ---- 319
 マシンスタックとは ---- 320
 マシンスタックの操作 ---- 321
 マシンスタックの用途 ---- 323
 スタックフレームとは ---- 324
 インストラクションポインタ ---- 325
 フラグレジスタ ---- 326

12.4  データの表現と配置 ---- 328
 符号なし整数の表現 ---- 328
 符号付き整数の表現 ---- 328
 負の整数の表現と2 の補数 ---- 329
 エンディアン ---- 330
 アラインメント ---- 331
 構造体の表現 ---- 332

第 13 章  x86 アセンブラプログラミング 335

13.1  GNU アセンブラによるプログラミング ---- 336
 GNU アセンブラ ---- 336
 アセンブリ言語によるHello, World! ---- 336
 GNU アセンブラによるアセンブル ---- 337

13.2  GNU アセンブラの文法 ---- 340
 アセンブリ版Hello, World! ---- 340
 インストラクション ---- 341
 ディレクティブ ---- 341
 ラベル ---- 342
 コメント ---- 343
 ニモニックサフィックス ---- 343
 さまざまなオペランド ---- 344
 間接メモリ参照 ---- 345
 x86 インストラクションセットの概要 ---- 348

13.3  転送命令 ---- 350
 mov 命令 ---- 350
 push 命令とpop 命令 ---- 352
 lea 命令 ---- 353
 movsx 命令とmovzx 命令 ---- 354
 符号拡張とゼロ拡張 ---- 355

13.4  算術演算命令 ---- 357
 add 命令 ---- 357
 キャリーフラグ ---- 358
 sub 命令 ---- 358
 imul 命令 ---- 359
 idiv 命令とdiv 命令 ---- 360
 inc 命令 ---- 362
 dec 命令 ---- 362
 neg 命令 ---- 362

13.5  ビット演算命令 ---- 364
 and 命令 ---- 364
 or 命令 ---- 365
 xor 命令 ---- 365
 not 命令 ---- 366
 sal 命令 ---- 366
 sar 命令 ---- 367
 shr 命令 ---- 367

13.6  演算の制御 ---- 369
 jmp 命令 ---- 369
 条件付きジャンプ命令(jz、jnz、je、jne、……) ---- 370
 cmp 命令 ---- 372
 test 命令 ---- 372
 フラグを取り出す命令(SETcc) ---- 373
 call 命令 ---- 374
 ret 命令 ---- 375

第 14 章  関数呼び出しと変数 377

14.1  手続き呼び出し規約 ---- 378
 手続き呼び出し規約とは ---- 378
 Linux/x86 の手続き呼び出し規約 ---- 379

14.2  Linux/x86 での関数呼び出し ---- 381
 呼び出し完了まで ---- 381
 関数本体の実行開始まで ---- 382
 呼び出し元への復帰まで ---- 384
 後始末完了まで ---- 385
 関数呼び出しのまとめ ---- 385

14.3  Linux/x86 での関数呼び出しの詳細 ---- 389
 レジスタの保存と復帰 ---- 389
 caller-save レジスタとcallee-save レジスタ ---- 390
 caller-save レジスタとcallee-save レジスタの活用 ---- 391
 大きな値と浮動小数点数の返しかた ---- 392
 他のプラットフォームでの手続き呼び出し規約 ---- 394

第 15 章  式と文のコンパイル 395

15.1  コンパイル結果の調査 ---- 396
 cbc での調査方法 ---- 396
 gcc での調査方法 ---- 398

15.2  x86 アセンブリのオブジェクト表現とDSL ---- 399
 アセンブリを表現するクラス ---- 399
 アセンブリオブジェクトの表示 ---- 401

15.3  cbc のx86 アセンブリDSL ---- 403
 DSL によるアセンブリオブジェクトの生成 ---- 403
 レジスタの表現 ---- 404
 即値とメモリ参照の表現 ---- 406
 インストラクションの表現 ---- 406
 ディレクティブ、ラベル、コメントの表現 ---- 407

15.4  CodeGenerator クラスの概要 ---- 409
 CodeGenerator クラスのフィールド ---- 409
 CodeGenerator クラスの処理の概要 ---- 410
 compileStmts メソッドの実装 ---- 411
 cbc のコンパイル戦略 ---- 412

15.5  単純な式のコンパイル ---- 415
 Int ノードのコンパイル ---- 415
 Str ノードのコンパイル ---- 415
 Uni ノードのコンパイル(1)ビット否定 ---- 417
 Uni ノードのコンパイル(2)論理否定 ---- 419

15.6  二項演算のコンパイル ---- 421
 Bin ノードのコンパイル ---- 421
 compileBinaryOp メソッドの実装 ---- 422
 除算と剰余の実装 ---- 423
 比較演算の実装 ---- 424

15.7  変数の参照と代入 ---- 426
 Var ノードのコンパイル ---- 426
 Addr ノードのコンパイル ---- 428
 Mem ノードのコンパイル ---- 429
 Assign ノードのコンパイル ---- 429

15.8  ジャンプ文のコンパイル ---- 432
 LabelStmt ノードのコンパイル ---- 432
 Jump ノードのコンパイル ---- 432
 CJump ノードのコンパイル ---- 433
 Call ノードのコンパイル ---- 434
 Return ノードのコンパイル ---- 435

第 16 章  スタックフレームの割り当て 437

16.1  マシンスタックの操作 ---- 438
 cbc のスタックフレーム ---- 438
 スタックポインタ操作の方針 ---- 439
 関数本体のコンパイル手順 ---- 440

16.2  引数とローカル変数へのメモリ参照割り当て ---- 442
 この節の概要 ---- 442
 引数へのメモリ参照割り当て ---- 442
 ローカル変数へのメモリ参照割り当て:方針 ---- 444
 ローカル変数へのメモリ参照割り当て ---- 446
 スコープ内のローカル変数の処理 ---- 447
 アラインメントの計算 ---- 448
 子スコープの変数への割り当て ---- 449

16.3  仮想スタックによるテンポラリ変数の割り当て ---- 451
 仮想スタックの目的 ---- 451
 仮想スタックのインターフェイス ---- 452
 仮想スタックの構造 ---- 453
 virtulPush メソッドの実装 ---- 454
 VirtualStack#extend メソッドの実装 ---- 454
 VirtualStack#top メソッドの実装 ---- 455
 virtulPop メソッドの実装 ---- 455
 VirtualStack#rewind メソッドの実装 ---- 456
 仮想スタックの動作 ---- 456

16.4  マシンスタックアクセスのオフセット調整 ---- 457
 この節の概要 ---- 457
 StackFrameInfo クラス ---- 458
 使われているcallee-save レジスタの算出 ---- 459
 テンポラリ変数領域のサイズの算出 ---- 460
 ローカル変数のオフセット調整 ---- 460
 テンポラリ変数のオフセット調整 ---- 461

16.5  プロローグ・エピローグの生成 ---- 462
 この節の概要 ---- 462
 プロローグの生成 ---- 463
 エピローグの生成 ---- 464

16.6  alloca の実装 ---- 466
 alloca 関数とは ---- 466
 実装の方針 ---- 467
 alloca 関数の影響 ---- 467
 alloca 関数の実装 ---- 468

第 17 章  最適化の手法 471

17.1  最適化とは ---- 472
 いろいろな最適化 ---- 472
 最適化の例 ---- 472
 定数の畳み込み ---- 473
 式の単純化 ---- 473
 演算強度の低減 ---- 473
 共通部分式の削除 ---- 474
 不要命令の削除 ---- 474
 関数インライン展開 ---- 475

17.2  最適化の分類 ---- 476
 手法による最適化の分類 ---- 476
 対象範囲による最適化の分類 ---- 477
 適用段階による最適化の分類 ---- 478

17.3  cbc での最適化 ---- 479
 cbc における最適化の方針 ---- 479
 cbc で実装した最適化 ---- 479
 cbc での最適化の実装 ---- 480

17.4  より強力な最適化 ---- 481
 パターンマッチによる命令選択 ---- 481
 レジスタ割り当て ---- 482
 コントロールフロー解析 ---- 483
 大規模なデータフロー解析とSSA 形式 ---- 483
 まとめ ---- 484

第4 部 リンクとロード

第 18 章  オブジェクトファイルの生成 487

18.1  ELF ファイルの構造 ---- 488
 ELF の目的 ---- 488
 ELF のセクションとセグメント ---- 489
 オブジェクトファイルの主要なELF セクション ---- 491
 readelf コマンドによるセクションヘッダの表示 ---- 492
 readelf コマンドによるプログラムヘッダの表示 ---- 493
 readelf コマンドによるシンボルテーブルの表示 ---- 495
 readelf コマンドのオプション ---- 496
 DWARF フォーマットとは ---- 497

18.2  グローバル変数のELF ファイルでの表現 ---- 498
 任意のELF セクションへの割り当て ---- 498
 一般的なELF セクションへの割り当て ---- 499
 .bss セクションの確保 ---- 499
 コモンシンボル ---- 500
 グローバル変数に対応するシンボルの登録 ---- 502
 シンボルの付帯情報の登録 ---- 503
 コモンシンボルの付帯情報の登録 ---- 504
 まとめ ---- 505

18.3  グローバル変数のコンパイル ---- 507
 generate メソッドの実装 ---- 507
 generateAssemblyCode メソッドの実装 ---- 507
 グローバル変数のコンパイル ---- 509
 即値のコンパイル ---- 510
 コモンシンボルのコンパイル ---- 512
 文字列リテラルのコンパイル ---- 513
 関数ヘッダの生成 ---- 514
 関数のコードサイズの計算 ---- 515
 まとめ ---- 516

18.4  オブジェクトファイルの生成 ---- 517
 as コマンド呼び出しの概要 ---- 517
 GNUAssembler クラスの呼び出し ---- 517
 as コマンドの呼び出し ---- 518

第 19 章  リンクとライブラリ 521

19.1  リンクの概要 ---- 522
 リンクの実行例 ---- 522
 gcc とGNU ld ---- 524
 リンカが扱うファイル ---- 526
 よく使われるライブラリ ---- 528
 リンカの入力と出力 ---- 528

19.2  リンクとは ---- 530
 リンクで行われる処理 ---- 530
 セクションのマージとは ---- 530
 再配置とは ---- 531
 シンボルの解決とは ---- 533

19.3  ダイナミックリンクとスタティックリンク ---- 535
 2 つのリンク手法 ---- 535
 ダイナミックリンクの利点 ---- 536
 ダイナミックリンクの欠点 ---- 536
 ダイナミックリンクの実行例 ---- 537
 スタティックリンクの実行例 ---- 538
 ライブラリの検索規則 ---- 539

19.4  ライブラリの作成 ---- 541
 静的ライブラリの作成 ---- 541
 Linux での共有ライブラリの管理 ---- 542
 共有ライブラリの作成 ---- 543
 作成した共有ライブラリとのリンク ---- 545

第 20 章  プログラムのロード 547

20.1  ELF セグメントのロード ---- 548
 mmap システムコールによるファイルのマップ ---- 548
 プロセスのメモリイメージ ---- 549
 メモリ領域の属性 ---- 551
 ELF セグメントとメモリ領域の対応 ---- 551
 ELF ファイルと対応しないメモリ領域 ---- 554
 ELF ファイルのロードの実装 ---- 555

20.2  ダイナミックリンクの過程 ---- 557
 ダイナミックリンカローダとは ---- 557
 プログラムの起動から終了までの概要 ---- 558
 ld.so の起動 ---- 559
 カーネルから渡される情報 ---- 560
 AUX ベクタ ---- 561
 共有ライブラリの読み込み ---- 562
 シンボルの解決と再配置 ---- 564
 初期化コードの実行 ---- 565
 メインプログラムの開始 ---- 566
 終了処理の実行 ---- 567
 ld.so が解釈する環境変数 ---- 568

20.3  動的ロード ---- 570
 動的ロードとは ---- 570
 Linux での動的ロード ---- 570
 動的ロードの仕組み ---- 571

20.4  GNU ld によるリンク ---- 573
 cbc 用ld オプションの構築 ---- 573
 C ランタイム ---- 574
 実行可能ファイルの作成 ---- 575
 共有ライブラリの生成 ---- 576

第 21 章  位置独立コードの生成 579

21.1  位置独立コードとは ---- 580
 位置独立コードとは ---- 580
 グローバルオフセットテーブル(GOT) ---- 582
 GOT のアドレス取得 ---- 582
 GOT を使ったグローバル変数アクセス ---- 584
 GOT を使ったファイル内グローバル変数へのアクセス ---- 585
 手続きリンクテーブル(PLT) ---- 585
 PLT エントリの呼び出し ---- 588
 位置独立な実行可能ファイル:PIE ---- 588

21.2  グローバル変数参照の実装 ---- 591
 GOT アドレスの取得 ---- 591
 PICThunk メソッドの実装 ---- 592
 重複した関数の削除と非可視属性 ---- 593
 GOT アドレスのロード ---- 594
 locateSymbols メソッドの実装 ---- 595
 グローバル変数の参照 ---- 596
 グローバル変数へのアクセス:位置独立コードの場合 ---- 597
 関数のシンボル ---- 598
 文字列定数の参照 ---- 600

21.3  リンカ呼び出しの実装 ---- 602
 実行可能ファイルの生成 ---- 602
 generateSharedLibrary メソッド ---- 604

21.4  プログラムの解析から実行まで ---- 606
 ビルドとロードの過程 ---- 606
 字句解析 ---- 607
 構文解析 ---- 608
 中間表現の生成 ---- 609
 コード生成 ---- 610
 アセンブル ---- 611
 共有ライブラリの生成 ---- 612
 実行可能ファイルの生成 ---- 613
 ロード ---- 613

第 22 章  本書を読み終えたあとに 615

22.1  書籍紹介 ---- 616
 コンパイラ全体について ---- 616
 構文解析について ---- 617
 アセンブリ言語について ---- 618
22.2  リンク・ロードについて ---- 619
22.3  さまざまな言語機能 ---- 620
 例外の実装に関する書籍 ---- 620
 ガーべージコレクションとは ---- 621
 ガーベージコレクションに関する書籍 ---- 621
 オブジェクト指向言語の実装 ---- 622
 関数型言語 ---- 623

付録 625
A.1 参考文献 ---- 626
A.2 オンラインドキュメント ---- 629
A.3 ソースコード ---- 630
索引 ---- 631