リンカーとライブラリ

シンボルの検索

オブジェクトがシンボルを必要とする場合、実行時リンカーはそのシンボルを、オブジェクトのシンボル要求の検索範囲と、プロセス内の各オブジェクトによって提供されるシンボルの可視性に基づいて検索します。これらの属性は、読み込まれる時に、オブジェクトのデフォルトとして使用され、dlopen(3DL) の特別なモードとしても使用され、さらに、場合によっては、オブジェクトの構築時に、オブジェクト内に記録されます。

平均的なユーザーであれば、動的実行プログラムとその依存関係、および dlopen(3DL) を通じて入手したオブジェクトに適用されるデフォルトのシンボル検索モードが、理解できるようになります。前者の検索モードについては、次の項、デフォルトの検索で概要を説明します。種々のシンボル検索に活用できる後者については、シンボル検索で説明しています。

リンカーの -B direct オプションを使って動的オブジェクトを作成すると、別のシンボル検索モデルが使用されます。実行時リンカーは、リンク編集時に結合されたオブジェクトからシンボルを直接検索します。このモデルの詳細は、直接結合を参照してください。

デフォルトの検索

動的実行プログラムと、ともに読み込まれるすべての依存関係には、「ワールド」検索範囲と、「大域」シンボル可視性が割り当てられます 。シンボル検索を参照してください。 実行時リンカーは、動的実行プログラムまたはこの実行プログラムとともに読み込まれた依存関係すべてを調べてシンボルを検出するために、オブジェクトを順番に検索します。まず動的実行プログラムから検索してから、 オブジェクトが読み込まれた順番に依存関係を検索します。

前の項で説明したように、ldd(1) を使用すると、動的実行プログラムの依存関係は読み込まれた順番にリストされます。たとえば、共有オブジェクト libbar.so.1 がシンボル foo の再配置を行うためにそのアドレスを必要とし、かつ共有オブジェクトが動的実行プログラム prog の依存関係であるとします。


$ ldd prog
        libfoo.so.1 =>   /home/me/lib/libfoo.so.1
        libbar.so.1 =>   /home/me/lib/libbar.so.1

実行時リンカーは、foo の検索を、最初に動的実行プログラム prog 内で実行し、次に共有オブジェクト /home/me/lib/libfoo.so.1 内で、最後に共有オブジェクト /home/me/lib/libbar.so.1 内で実行します。


注 –

シンボル検索は、シンボル名のサイズが増大し依存関係の数が増加すると、特にコストのかかる処理になる可能性があります。このパフォーマンスについての詳細は、性能に関する考慮事項で説明しています。これに代わる検索モデルについては、直接結合を参照してください。


割り込み (interposition)

最初に動的実行プログラム内でシンボルの検索を行い、次に各依存関係内で検索を行うという実行時リンカーのデフォルトのメカニズムは、要求されたシンボルの最初の出現が、この検索を満足させることを意味しています。そのため、同じシンボルの複数のインスタンスが存在する場合は、最初のインスタンスが、他のすべてのインスタンスに割り込みます。共有オブジェクトの処理も参照してください。

直接結合

リンカーの -B direct オプションを使ってオブジェクトを作成すると、参照されるシンボルと、定義を提供する依存条件との関係は、オブジェクトに記録されます。実行時リンカーは、デフォルトのシンボル検索モデルを使用する代わりに、この情報を使って関連するオブジェクトから直接シンボルを検索します。


注 –

-B direct オプションを使用すると、遅延読み込みも有効になります。これは、リンク編集のコマンド行の先頭に -z lazyload オプションを指定するのと同じことです 。動的依存関係の遅延読み込みを参照してください。


直接結合モデルでは、多数のシンボル再配置や依存関係を伴う動的プロセスでのシンボル検索オーバーヘッドを大幅に削減できます。さらに、このモデルでは、同じ名前の複数のシンボルを、それらが直接結合されている個々のオブジェクトから見つけることができます。

直接結合ではデフォルトの検索モデルがバイパスされるため、従来から使用されている割り込みシンボルが迂回される可能性があります。デフォルトのモデルでは必ず、1 つのシンボルへのすべての参照は同じ 1 つの定義に結合されます。

直接結合環境でも、オブジェクト単位で、割り込みを行うことができます。それには、オブジェクトが割り込み処理として識別される必要があります。環境変数 LD_PRELOAD を使ってオブジェクトを読み込むか、リンカーの -z interpose オプションを使ってオブジェクトを作成すると、オブジェクトは割り込み処理として識別されます。 実行時リンカーは、直接結合されたシンボルを検索する際に、割り込み処理として識別されたオブジェクトを最初に探してから、シンボル定義を指定するオブジェクトを探します。


注 –

直接結合を実行時に無効にするには、環境変数 LD_NODIRECT にヌル以外の値を設定します。