3 ELF でプログラムを作るには

この章の目次へ

3.1 普通のプログラムの場合

ELF 形式でプログラムを作るには gcc を普通に使うだけです。 a.out 形式でコンパイルするには gcc -b i486-linuxaout としてく ださい。

そろそろ ``もし a.out 形式のコンパイラがデフォルトで生成する実行プログ ラムの名前が a.out なら、ELF コンパイラがデフォルトで生成する プログラムの名前は何と言うの?''という問いに答えましょう。やっぱり a.out 、というのが答えなんです。残念でしたか :-)

3.2 ライブラリの作り方

共有ライブラリとして libfoo.so を作る基本的な手順は以下の通りです。


$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
$ ln -s libfoo.so.1.0 libfoo.so.1
$ ln -s libfoo.so.1 libfoo.so
$ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

これで libfoo.so.1.0 と言う共有ライブラリができ、ld が識別す べきリンク(libfoo.so) も張られ、動的リンカも見つけることがで きます(libfoo.so.1)。テストのために、このプログラムのあるディ レクトリを LD_LIBRARY_PATH に追加しています。

もし作った共有ライブラリがちゃんと動くようなら、適切な場所、例えば /usr/local/lib にでも移して、必要なリンクを張りましょう。 libfoo.solibfoo.so.1 を指すようにリンクを張って、 マイナーバージョンナンバーが変わる度に update しなくても済むようにして おきましょう。libfoo.so.1 から libfoo.so.1.0 へのリンクは ldconfig によって、たいていのシステムでは起動時に更新されるよ うにっています。


$ su
# cp libfoo.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )

3.3 動的ローディングを使うプログラム

この問題については H J Lu 作の「ELF プログラミングドキュメント」と ld.so パッケージに附属の dlopen(3) のマニュアルページにくわし く解説してあります。ここでは簡単な例を示すに留めましょう。以下のプログ ラムを -ldl オプションを付けてリンクしてみてください。


#include <dlfcn.h>
#include <stdio.h>

main()
{
  void *libc;
  void (*printf_call)();

  if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
  {
    printf_call=dlsym(libc,"printf");
    (*printf_call)("hello, world\n");
  }

}

3.4 デバッグ

お手持ちの gdb は ELF プログラムに対しても特に変更なしで動くはず です(たいていの場合)。しかし、tsx-11 の GCCディレクトリにある新し いバージョンの gdb は動的ローディングにも対応し、ELF 形式のコアにも対 応しているそうです。

しかしながら、この文書を書いている時点では、ELF プログラムがコアダンプ するためにはカーネルにパッチを当てる必要があります。問題が多少専門的に なるので、この文書ではそこまで扱いません。

次の章へ , 前の章へ

この章の目次へ, この文書の目次へ

この文書の最初へ , この章の最初へ