Oracle® Solaris 11.2 リンカーとライブラリガイド

印刷ビューの終了

更新: 2014 年 7 月
 
 

再配置シンボルの検索

実行時リンカーには、オブジェクトが必要とするシンボルを実行時に検索する責任があります。一般にユーザーは、動的実行可能ファイルやその依存関係および dlopen(3C) によって取得されたオブジェクトに適用される、デフォルトの検索モデルを理解するようになります。しかし、オブジェクトのシンボル属性や特定の結合要件が原因で、より複雑なシンボル検索が行われることもあります。

オブジェクトの 2 つの属性は、シンボル検索に影響を与えます。最初の属性は、要求元オブジェクトのシンボルの検索範囲です。2 つ目の属性は、プロセス内の各オブジェクトによって提供されるシンボルの可視性です。

これらの属性は、オブジェクトを読み込む際、デフォルトとして適用できます。これらの属性は、dlopen(3C) の特定のモードとしても提供できます。場合によっては、これらの属性をオブジェクトの構築時にオブジェクト内に記録することができます。

オブジェクトは、world 検索範囲または group 検索範囲、あるいはその両方を定義できます。

world

オブジェクトは、プロセス内のほかの任意の大域オブジェクト内でシンボルを検索できます。

group

オブジェクトは、同じグループのオブジェクト内のシンボルを検索できます。dlopen(3C)を使用して入手されたオブジェクトから作成された依存関係ツリー、またはリンカーの –B group オプションを使用して構築されたオブジェクトから作成された依存関係ツリーは、固有のグループを形成します。

オブジェクトは、オブジェクトのエクスポートされたシンボルがグローバルに参照可能か、ローカルに参照可能かを定義できます。

global

オブジェクトのエクスポートされたシンボルは、ワールド検索範囲を持つ任意のオブジェクトから参照できます。

local

オブジェクトのエクスポートされたシンボルは、同じグループを構成するほかのオブジェクトからのみ参照できます。

実行時のシンボル検索は、シンボルの可視性によって指定することもできます。STV_SINGLETON 可視性を割り当てたシンボルは、すべてのシンボル検索範囲から除外されます。シングルトンシンボルへのすべての参照は、プロセス内で最初に定義されているシングルトンにバインドされます。Table 12–23 を参照してください。

もっとも単純な形のシンボル検索については、次のセクションデフォルトのシンボル検索で説明します。一般に、シンボル属性はさまざまな形の dlopen(3C) によって利用されます。これらのシナリオについては、シンボルの検索に記載されています。

動的なオブジェクトで直接結合を行うと、別のシンボル検索モデルが提供されます。このモデルでは、実行時リンカーは、リンク編集時に結合されたオブジェクトからシンボルを直接検索します。Chapter 6, 直接結合を参照してください。

デフォルトのシンボル検索

動的実行可能プログラムと、ともに読み込まれるすべての依存関係には、「ワールド」検索範囲と、「大域」シンボル可視性が割り当てられます 。動的実行可能ファイルや、それとともに読み込まれた依存関係を対象としたデフォルトのシンボル検索では、各オブジェクトが検索されます。まず動的実行可能プログラムから検索してから、 オブジェクトが読み込まれた順番に依存関係を検索します。

ldd(1) を使用すると、動的実行可能ファイルの依存関係は読み込まれた順にリストされます。たとえば、動的実行可能ファイル prog で、依存関係として libfoo.so.1libbar.so.1 が指定されているとします。

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

シンボル bar の再配置が要求された場合、実行時リンカーは最初に動的実行可能ファイル progbar を検索します。シンボルが見つからない場合は、次に共有オブジェクト /home/me/lib/libfoo.so.1 を検索し、最後に共有オブジェクト /home/me/lib/libbar.so.1 を検索します。


注 - シンボル検索は、シンボル名のサイズが増大し依存関係の数が増加すると、特にコストのかかる処理になる可能性があります。この性能については、Chapter 7, システムのパフォーマンスを最適化するオブジェクトの構築で詳しく説明しています。これに代わる検索モデルについては、Chapter 6, 直接結合を参照してください。

デフォルトの再配置処理モデルでは、遅延読み込み環境の遷移も提供します。現在読み込まれているオブジェクト内でシンボルが見つからない場合は、そのシンボルを特定するために、保留となっている遅延読み込みオブジェクトが処理されます。この読み込みによって、依存関係を完全には定義していないオブジェクトを補います。ただし、これにより遅延読み込みの利点が失われることがあります。

実行時割り込み

デフォルトで、実行時リンカーはまず動的実行可能プログラム内でシンボルを検索したあと、それぞれの依存関係を検索します。このモデルでは、必要なシンボルが最初に現れた時点で検索条件が満たされます。そのため、同じシンボルの複数のインスタンスが存在する場合は、最初のインスタンスが、ほかのすべてのインスタンスに割り込みます。

シンボル解決がどのように割り込みの影響を受けるかの概要については、単純な解決で説明しています。シンボルの可視性を変更し、偶発的な割り込みの可能性を低くするメカニズムは、シンボル範囲の縮小で説明しています。


注 - STV_SINGLETON 可視性を割り当てたシンボルでは、一種の割り込みが行われます。シングルトンシンボルへのすべての参照は、プロセス内で最初に定義されているシングルトンにバインドされます。Table 12–23 を参照してください。

オブジェクトが割り込み処理として明示的に識別されている場合、割り込みをオブジェクト単位で行えます。環境変数 LD_PRELOAD を使ってオブジェクトを読み込むか、リンカーの –z interpose オプションを使ってオブジェクトを作成すると、オブジェクトは割り込み処理として識別されます。実行時リンカーがシンボルを検索する場合、割り込むものとして識別されたオブジェクトはアプリケーションよりもあとで検索されますが、その他の依存関係よりは前に検索されます。

割り込み処理により提供されるすべてのインタフェースの使用が保証されるのは、プロセス再配置が行われる前に割り込み処理が読み込まれる場合のみです。環境変数 LD_PRELOAD を使用して提供される割り込み処理、またはアプリケーションの非遅延読み込み依存関係として確立される割り込み処理は、再配置処理が始まる前に読み込まれます。再配置が始まったあとでプロセスに挿入される割り込み処理は、通常の依存関係に降格されます。割り込み処理を降格できるのは、割り込み処理が遅延読み込みされた場合、または dlopen(3C) を使用した結果として読み込まれた場合です。前者のカテゴリは ldd(1) を使用して検出できます。

$ ldd -Lr prog
        libc.so.1 =>     /lib/libc.so.1
        foo.so.2 =>      ./foo.so.2
        libmapmalloc.so.1 =>     /usr/lib/libmapmalloc.so.1
        loading after relocation has started: interposition request \
            (DF_1_INTERPOSE) ignored: /usr/lib/libmapmalloc.so.1

注 - 遅延読み込みを行うために依存関係を処理している間に、明示的に定義された割り込み処理をリンカーが検出した場合、その割り込み処理は非遅延読み込み可能依存関係として記録されます。

動的実行可能ファイル内の個々のシンボルは、INTERPOSE mapfile キーワードを使って割り込み処理として定義できます。このメカニズムは –z interpose オプションを使用する方法よりも優先されるので、依存関係が展開されていくときに発生する可能性のある逆割り込みの影響を受けにくくなります。明示的な割り込みの定義を参照してください。