最終更新:2009-07-20 (月) 01:12:46 (3319d)  

参考図書/ふつうのコンパイラを作ろう はてなブックマークを見る
Top / 参考図書 / ふつうのコンパイラを作ろう

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

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

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

1.1 本書の概要 ---- 2

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

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

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

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

19.2 リンクとは ---- 530

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

19.3 ダイナミックリンクスタティックリンク ---- 535

19.4 ライブラリの作成 ---- 541

第 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

22.2 リンクロード?について ---- 619

22.3 さまざまな言語機能? ---- 620

付録 625

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

参考