リンカーとライブラリ

再配置が実行されるとき

再配置は、実行されるタイミングで区別できます。この区別は、再配置されたオフセットに対する参照の種類によるもので、次のいずれかになります。

「即時参照」とは、オブジェクトが読み込まれたときにただちに決定しなければならない再配置のことです。この参照は、一般にオブジェクトコードで使用されるデータ項目、関数ポインタ、および位置依存共有オブジェクトからの関数呼び出しに対するものです。即時参照では、再配置された項目が参照されたことを実行時リンカーは認識できません。このため、すべての即時参照は、オブジェクトが読み込まれたら、アプリケーションが制御を獲得または再獲得する前に、再配置が完了する必要があります。

「遅延参照」とは、オブジェクトの実行時に決定できる再配置のことです。通常は、位置独立共有オブジェクトから大域関数への呼び出しか、動的実行可能ファイルから外部関数への呼び出しです。遅延参照を行う動的モジュールをコンパイルおよびリンク編集しているときに、関連付けられた関数呼び出しは、プロシージャリンクテーブルのエントリへの呼び出しに変換されます。 これらのエントリは、.plt セクションを構成します。 プロシージャのリンクテーブルの各エントリは、再配置への遅延参照になります。

プロシージャのリンクテーブルのエントリは、最初に呼び出されたときに、制御が実行時リンカーに渡るように生成されます。実行時リンカーは、関連付けられたオブジェクト内で必要なシンボルを検索し、情報を書き換え、その後のプロシージャリンクテーブルのエントリへの呼び出しが、関数を直接呼び出すようにします。遅延参照では、関数が最初に呼び出されるまで、再配置を遅延させることができます。この処理は、「遅延」結合と呼ばれることがあります。

実行時リンカーのデフォルトモードでは、プロシージャのリンクテーブルの再配置は、常に遅延結合として実行されます。デフォルトモードを無効にするには、環境変数 LD_BIND_NOW にヌル以外の任意の値を設定します。この環境変数に値を設定すると、実行時リンカーは、オブジェクトが読み込まれてから、アプリケーションが制御を獲得または再獲得するまでの間に、即時参照および遅延参照を再配置します。たとえば、環境変数を次のように設定すると、ファイル prog とその依存先の再配置は、制御がアプリケーションに移る前に行われます。


$ LD_BIND_NOW=1 prog

オブジェクトにアクセスするときは、RTLD_NOW として定義されたモードで、 dlopen(3DL) を使用することもできます。リンカーの -z now オプションを使用してオブジェクトを構築すれば、オブジェクトが読み込まれたときに再配置を完了させることができます。この再配置オプションは、実行時に指定したオブジェクトの依存先すべてに波及します。


注 –

前述の即時参照と遅延参照の例は、標準的なものですが、プロシージャのリンクテーブルエントリの作成は、リンク編集の入力として使用する再配置可能オブジェクトファイルが提供する再配置情報によって制御されます。R_SPARC_WPLT30R_386_PLT32 などの再配置レコードには、プロシージャのリンクテーブルエントリの作成が指定されています。これらのレコードは、位置独立コードで常に使用されます。ただし、動的実行可能ファイルの位置は固定されているため、リンク編集時に決定された外部関数参照は、元の再配置レコードに関係なく、プロシージャのリンクテーブルのエントリに変換できます。