gccは3つの主要なステップからなる
gccは3つの主要なステップからなる
1. Cのソースをアセンブリに変換
- gccはC compilerを呼び出し,それが.cをターゲットマシンのアセンブリコードの.sに変換する
- C compilerは前処理,lexical 解析,parse,code生成などのフェーズを持つ
2. assembly codeをobject codeに変換
- すべてのコンピュータは自身のマシン命令を持つ.Assemblerはassembly codeをバイナリの機械語に変換するプログラム
- 結果の.oファイルはOBJECT codeと呼ばれる.
- gccの第二ステップは.sを.oに変換するASSEMBLERを呼び出すこと
- 各.o ファイルは次を含む
3. LINKする
- プログラムは互いに依存する複数の.oファイルからなることがあり,ccの最後のステップはLinkerですべての.oファイルと必要なライブラリを結合して一つのbinary executableにすること
- 具体的には,
- .oファイルのすべてのCODEセクションを一つのcode sectionにする
- Cプログラムでは結合されたCode sectionはデフォルトCスタートアップコードcrt0.oで始まり,それがmian()を呼ぶ.(これがmain()がなければならない理由)
- すべてのDATA secitonを一つのData sectionに結合する.結合されたdata sectionは初期化されたglobal変数と初期化されたstatic local変数のみを含む
- すべてのBSSセクションを一つのbssセクションに結合する
- .oファイルのrelocation情報を使って結合されたcode section中のpointersと結合されたDataとbss sectionのoffsetsを調節
- symbol tableを使い,個別の.oファイルのcross referenceを解決する.例えば,compilerがc = mysum(a,b)をt1.cで見ても,mysumがどこにあるかわからない.そこで,compilerはt1.oに空白(ゼロ)をmysynのentry addressとして残しておいて,symbol tableに記録する
- linkerがt1.oとt2.oを結合したときlinkerは,combined Code sectionでmysumの場所を知る
- t1.oのblankをmysumのエントリアドレスで埋める
- 他のcross referenceされたsymbolも同様.
- static globalsはsymbol tableにはないので,linkerは利用できない.
- 異なるファイルからreference static globalsを参照するいかなる試みもreference errorを出す
- .oファイルがundefined なシンボルや関数名を参照していれば,linkerはcross reference errorを出す
- すべてのcross referenceが解決されれば,linkerは結果を結合されたファイルにa.outとして書く.これはバイナリ実行ファイルである.
- .oファイルのすべてのCODEセクションを一つのcode sectionにする
K.C.Wang, Systems Programming in Unix/Linux, 2018, pp.28-29, Springer, https://www.springer.com/gp/book/9783319924281