# ELFローダー (overview)

## 説明

ELライブラリは再配置可能 モジュール システムです。
ゲーム プログラム中でプログラムモジュールを動的に読み込んだり、解放しながら、メインメモリを効率よく使用することができます。
他のオペレーティングシステムのダイナミック リンク ライブラリとは異なり、このライブラリでは、メモリの割り当てと解放および ROM からのモジュールの読み込みはゲームプログラム側に任されています。
ELライブラリは、ひとつの静的モジュール(アプリケーションプログラム)とひとつの静的モジュール情報(makelst生成プログラム)、複数の動的（＝再配置可能）モジュール(.o もしくは .aファイル)で構成されます。静的モジュールが動的モジュールのメモリ配置を制御できます。 静的モジュールは通常のSRLファイルとしてビルドします。静的モジュールは動的モジュールから参照される共通の関数や変数を含むことができます。
動的（＝再配置可能）モジュールは静的モジュール内の関数を呼び出したり、変数を参照することができます。そのためにはmakelstツールを使用して、静的モジュールの関数情報をELライブラリに渡すプログラムを自動生成し、必要ならば変数情報も追加し、静的モジュール側から呼び出す必要があります。
さらに、動的モジュールはすでにメモリに読み込まれているその他の動的モジュールの関数を呼び出したり、変数を参照することもできます。
静的モジュールから動的（＝再配置可能）モジュールの関数や変数をシンボル名を指定することによってアクセスすることができます。
これは動的モジュールが静的モジュール内の関数を呼び出す場合と異なりプログラム側が意識して使用することになります。
動的（＝再配置可能）モジュールのプログラムは通常のCプログラムとまったく同様に記述することができます。また、動的モジュールはコンパイラ、リンカが生成する .o もしくは .a ファイルをそのまま使用できます。しかし、通常コンパイルしたものはプログラムを動作させるために必要のないデバッグ情報を含んでおり、またデバッガを動作させるための情報も足りていません。通常コンパイルで生成されたファイルとは別に、アプリケーションに組み込む動的モジュールとしてデバッグ情報を削除したファイルと、デバッグを行いたいのであればデバッグ情報等を含んだファイルも必要となります。その際には、stripdebugツールを使用することになります。
デバッガに、デバッグ情報付き動的モジュールのパスを通知するためには RSF ファイルの RomSpec セクションに DllFile を追加する必要があります。詳しくは`makerom`を参照してください。
注意：ELライブラリはC++に対応していません。

#### 再配置可能 モジュールの作り方

##### 1. 動的側のプログラムをコンパイルしてオブジェクトファイル(.o もしくは .a)を生成する

ELライブラリはオブジェクトファイルそのものを動的モジュールとして扱うので、コンパイルした .o ファイルもしくは複数の .o ファイルをリンクした .a ファイルをそのまま使用することになります。ここでアプリケーションに組み込む動的モジュールとして、生成されたファイルをstripdebugツールにかけて、不必要なデバッグ情報を削除しサイズを小さくしたファイルと、デバッガに渡すデバッグ情報等の付属したファイルを用意します。

    % stripdebug.exe -o dll.a -O dll_debug.a a.a

##### 2. 静的側のプログラムをコンパイルしてオブジェクトファイル(.o)を生成する

makelstを使用して静的モジュール情報を生成するために、静的側のプログラムをコンパイルしてオブジェクトファイルにしておきます。

##### 3. すべての動的モジュールが静的モジュールにアクセスできるようにするプログラムを生成する

makelstを使用して静的モジュール情報を生成し、このプログラムを静的側にリンクすることで、すべての動的モジュールが静的モジュール側の必要な関数を参照できるようになります。

    % makelst.exe -o staticsymlist.c --static obj/ARM9-TS/Release/main.o ../../../../lib/ARM9-TS/Release/libos.a --dll dll/dll.a

##### 4. プログラムをビルドしてROMファイルを作成する

1.と3.でコンパイルしたオブジェクトファイルをリンクして実行ファイルを作成します。動的モジュールとなる .o もしくは .a ファイルは ROM ファイルとして組み込むようにして、SRLファイルを作成すれば完成です。

注意
デバッガを使用して動的モジュールのデバッグを行いたい場合には、EL_LinkFile関数を使用し、RSF ファイル中でデバッガに渡すファイルを指定する必要があります。

    RomSpec
    {
        File		dll.a
        DllFile		dll.a dll_debug.a ARM9
    }

また、動的モジュールとなるファイルは ROM ファイルとして組み込むようにしてください。

#### 動的モジュールの使い方

以下の説明は ROM にある動的モジュールをリンクする方法になります。

動的モジュールは、一般的なELF形式のデータになっています。

##### 1. 各モジュールの読み込み準備

EL_LinkFile 関数内では FS を使用して ROM にアクセスしているため、ROM ファイルシステムの初期化を行います。

    FS_Init( FS_DMA_NOT_USE );

##### 2. ELライブラリの初期化

EL_InitでELライブラリの初期化を行います。

    EL_Init(MY_Alloc, MY_Free);

##### 3. 動的モジュールの追加

EL_Link* 関数で動的モジュールをELライブラリに登録します。
ここでは、デバッガを使えるようにするため EL_LinkFile を使用することになります。

    my_dlld = EL_LinkFile( "rom:/data/dllA.a", lib_buf);

##### 4. リンクの解決

EL_AddStaticSymでmakelstで生成した静的モジュール側のシンボル情報をELライブラリに登録します。 その後、EL_ResolveAllで、登録した動的モジュールのリンクを解決します。

    EL_AddStaticSym();
    EL_ResolveAll();

##### 5. 動的モジュールの関数を呼び出す

EL_GetGlobalAdrに呼び出したい動的モジュール側の関数名(シンボル名)を与えて、関数ポインタをうけとります。 その関数ポインタから呼び出すことにより、目的の関数を使用することができます。

    dll_func = EL_GetGlobalAdr( my_dlld, "global_func\0");
    (*dll_func)();

##### 6. 動的モジュールをアンリンクする

使用しなくなった動的モジュールはアンリンクしてメモリから削除することが可能です。
アンリンク処理は EL_Unlink で行えるので、使用していたメモリはアプリ側で解放を行ってください。

    EL_Unlink( my_dlld );

## 参照

`EL関数一覧
` `makerom`

## 履歴

2009/01/16 ELライブラリがC++非対応であることを追記
2008/10/06 動的モジュールから静的モジュールの変数へのアクセスついて追記
2008/04/22 最新の仕様に対応
2007/08/07 初版