リンカーとライブラリ

追加オブジェクトの読み込み

実行時リンカーでは、環境変数 LD_PRELOAD を使用することにより、プロセスの初期設定中に新しいオブジェクトを取り込めるという、一歩進んだ柔軟性も提供しています。この環境変数は、特定の共有オブジェクトまたは再配置可能オブジェクトのファイル名に初期設定することも、複数のファイル名を空白で区切った文字列に初期設定することもできます。これらのオブジェクトは、動的実行可能プログラムの後で、依存関係よりも前に読み込まれます。これらのオブジェクトには、「ワールド」検索範囲と「大域」シンボル可視性が割り当てられます。

次の例では、動的実行可能プログラム prog が読み込まれ、そのあとに共有オブジェクト newstuff.so.1 が続きます。続いて、prog 内で定義された依存関係が読み込まれます。


$ LD_PRELOAD=./newstuff.so.1 prog

これらのオブジェクトが処理される順序は、ldd(1) を使用して表示できます。


$ ldd -e LD_PRELOAD=./newstuff.so.1 prog
        ./newstuff.so.1 => ./newstuff.so
        libc.so.1 =>     /lib/libc.so.1

次の例では、事前読み込みは少し複雑で時間がかかります。


$ LD_PRELOAD="./foo.o ./bar.o" prog

実行時リンカーは、最初に再配置可能オブジェクト foo.obar.o をリンク編集し、メモリー内に保持されていた共有オブジェクトを生成します。次にこのメモリーイメージは、この前の例で示した共有オブジェクト newstuff.so.1 の事前読み込みと同じ方法で、動的実行可能プログラムとその依存関係との間に挿入されます。ここでも、これらのオブジェクトが処理される順序は、ldd(1) を使用して表示できます。


$ ldd -e LD_PRELOAD="./foo.o ./bar.o" prog
        ./foo.o =>       ./foo.o
        ./bar.o =>       ./bar.o
        libc.so.1 =>     /lib/libc.so.1

動的実行可能ファイルのあとにオブジェクトを挿入するこれらのメカニズムにより、割り込み機能が提供されます。これらのメカニズムを使用すると、標準的な共有オブジェクト内に存在する関数の、新しい実装を試すことができます。この関数が組み込まれたオブジェクトをあらかじめ読み込むことにより、このオブジェクトは元のオブジェクトに割り込みます。そして、元の機能は、事前読み込みされた新しいバージョンによって完全に隠されてしまいます。

このほかにも事前読み込みは、標準的な共有オブジェクト内に常駐する関数を補強するために使用できます。新しいシンボルが元のシンボルに割り込むことで、新しい関数はいくつかの追加処理を実行できます。新しい関数は元の関数を呼び出すこともできます。このメカニズムでは通常、dlsym(3C) と特別なハンドル RTLD_NEXT を使って元のシンボルのアドレスを取得します。