以前適当に解決しようとした問題を調べた。といってもwiki.osdev.orgのC++の項目を読んだだけ。英語の読解力がろくに無いので間違えて理解したかもしれない。
ようは、OSというパトロンがいなくなったC++さんが路頭に迷わないための手引き。
以下自分の理解をまとめる。osdev.orgにはサンプルコードまで載っていて素敵です。
デフォルトのスタートアップコードを利用しない
デフォルトでは、G++はmainが呼び出される前に実行されるコードや、mainがreturnした後に呼ばれるコードをリンクしようとする。
なので、無効にするために-nostartfilesオプションをつける。
new/delete
必要な処理を無効にしてしまった以上は、自前で実装しなければならない。とりあえず、global/staticなオブジェクトのコンストラクタ、デストラクタを呼び出すコードを追加すればよい。
コンストラクタ、デストラクタではnew/delete(new[]/delete[]も)が必要なので、これらも実装しなければならないが、その際にメモリマネジメントの機能が必要になる。特定のアドレスにオブジェクトを作るplacement newというテクニックもあるらしい。
mainの前後
GCC(G++)はctors、dtorsというセクションにそれぞれ、 global/staticオブジェクトのコンストラクタ、デストラクタを登録する。
C++のコードにジャンプする前後にこれらのセクションの内容を処理する。セクションの境界を知るためにリンカスクリプトを書く。
__cxa_atexitは、__cxa_finalizeで呼ばれる,オブジェクトや共有リソースを破棄する時のハンドルを登録する。
C++のカーネルコードが終了したら__cxa_finalize(0)を呼ぶべき。 dctorの処理と__cxa_finalize(0)の呼び出しは両方するべきなのだろうか。まぁ、終了時の事はあまり気にしなくても動くので良いか。
__dso_handleはさようならするオブジェクトがDynamic Shared Objectかどうか判別する?
純粋仮想関数(pure virtual function)
純粋仮想関数がオーバライドされていないのに呼びだされる(?)ときのための関数を用意する。
どこかの.cpp内に、__cxa_pure_virtualという関数を作る。なお、__cxa_pure_virtualにはextern "C"でC言語のリンケージを指定する。
Local static variables
GCCはローカルなスタティック変数のコンストラクタの前後に、複数スレッドから同時に呼び出されないように保護するコードを挿入するらしい。
いままで気にした事が無いシンボル名が出てきたので、他のどこかのオプションで無効になってるのではなかろうか。標準ライブラリを無効にするところだろうか。
標準ライブラリ
無効にするために-nostdlibオプションをつける。
実行時型情報
無効にするために-fno-tffiオプションをつける。
例外
無効にするために-fno-exceptionsオプションをつける。
0 件のコメント:
コメントを投稿