グローバルインスタンスのコンストラクタが呼ばれない時の対策
処理系によっては、グローバルインスタンスのコンストラクタが呼ばれない場合がある。
これは、組み込み用途で使用するOSなどに多い。
今回、 TOPPERS ASP で ++ を使用するにあたって躓いたのでメモ。
TOPPERS JSPでは C++バインディングが用意されているが、 ASPでは用意されていない。よって、ユーザがC++を動作できるように、TOPPERS ASP を C++ を移植する必要がある。これについては、別のエントリで説明する。
手順
リンカスクリプトの修正
gcc 4.3 以降では、 グローバルインスタンスのコンストラクタは init_array セクションに設定される。
よって、リンカスクリプトで init_arrayセクションの開始アドレスと終了アドレスを取得できるようにする。
具体的には、以下のコードを追加する。
.init_array{
PROVIDE(init_array_start = .);
*(.init_array*);
*(SORT(.init_array*));
PROVIDE(init_array_end)
}
初期化ルーチンの追加
カーネルの初期化ルーチンからタスクのディスパッチが行われる前に、グローバルインスタンスのコンストラクタを呼んでやる。
グローバルインスタンスのコンストラクタは、先ほどのinit_array_start を用いて行う。
具体的には以下のコードを差し込む。
extern char init_array_start;
extern char init_array_end;
void init_global_ctor()
{
void (*p)() = &init_array_start;
for(;p < &init_array_end;p++)
{
(*p)();
}
}
TOPPERS ASPの場合、この関数をsta_ker()のdispatch()が呼ばれる前に実行すれば良い。
おしまい