リンカーとライブラリ

再配置が実行されるとき

再配置処理を、非シンボルとシンボルの 2 つのタイプに分けて簡素化し、簡単に説明してきましたが、さらに再配置処理の実行時に、これを区別すると便利です。このような、再配置されたオフセットに対して行われる参照のタイプによって、区別が実行されます。参照のタイプは、次のいずれかになります。

データ参照とは、アプリケーションコードによってデータ項目として使用されるアドレスを参照することです。実行時リンカーは、アプリケーションコードに関する知識がないため、このデータ項目がいつ参照されるか認識できません。そのため、データ再配置はすべて、アプリケーションが制御を入手する前の、処理の初期設定中に実行されます。

関数参照とは、アプリケーションコードによって呼び出された関数のアドレスを参照するものです。動的モジュールのコンパイルおよびリンク編集中に、大域関数の呼び出しは再配置されて、プロシージャのリンクテーブルエントリの呼び出しになります (これらのエントリにより、.plt セクションが構成されます)。

プロシージャのリンクテーブルのエントリは、最初に呼び出された制御が実行時リンカーに渡されたときに構成されます (「手続きリンクテーブル (プロセッサに固有)」を参照)。実行時リンカーは、要求されたシンボルを検索しアプリケーション内の情報を書き換えます。そのため、あとに発生する .plt エントリへの呼び出しは、関数に直接送信されます。このメカニズムを使用すると、このタイプの再配置を、関数の最初のインスタンスが呼び出されるまで延期することができます。この処理をレイジー結合と呼びます。

レイジー結合を実行する、実行時リンカーのデフォルトモードは、空文字以外の値に環境変数 LD_BIND_NOW を設定することにより上書きされます。この環境変数の設定を行うと、実行時リンカーは、プロセスの初期設定中にデータ参照と関数参照の両方の再配置を実行してから、アプリケーションに制御を転送します。次に例を示します。


$ LD_BIND_NOW=yes prog

ここでは、ファイル prog 内とその依存関係の中のすべての再配置は制御がアプリケーションに移る前に処理されることになります。

個々のオブジェクトも、オブジェクトが読み込み時に再配置処理が完了している必要があることを指示するために、リンカーの -z now オプションを使用して構築されます。この再配置の必要条件は、実行時にマークされたオブジェクトの依存関係にも伝達されます。