ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
リンカーとライブラリ Oracle Solaris 11 Information Library (日本語) |
直接結合を使用するオブジェクトは、シンボル参照と、定義を提供する依存関係との間の関係を保持します。実行時リンカーは、デフォルトのシンボル検索モデルを使用する代わりに、この情報を使って関連するオブジェクトから直接シンボルを検索します。
動的オブジェクトの直接結合情報はリンク編集時に記録されます。この情報は、該当オブジェクトのリンク編集時に指定された依存関係に対してのみ確立できます。-z defs オプションを使用すると、必要なすべての依存関係がリンク編集の一部として確実に提供されます。
直接結合を使用するオブジェクトは、直接結合を使用しないオブジェクトがあるプロセス内に存在できます。直接結合を使用しないオブジェクトは、デフォルトのシンボル検索モデルを使用します。
シンボル参照からシンボル定義への直接結合を確立するには、次のいずれかのリンク編集メカニズムを使用します。
-B direct オプションを使用する。このオプションは、構築されるオブジェクトとそのすべての依存関係との間に直接結合を確立します。またこのオプションは、構築中のオブジェクト内の任意のシンボル参照とシンボル定義との間に直接結合を確立します。
-B direct オプションを使用すると、遅延読み込みも有効になります。これは、リンカーのコマンド行の先頭に -z lazyload オプションを追加するのと同じです。この属性は「動的依存関係の遅延読み込み」で紹介されました。
-z direct オプションを使用する。このオプションは、構築されるオブジェクトから、コマンド行上でこのオプションに続いて指定される依存関係への直接結合を確立します。このオプションは、-z nodirect オプションと併用して、依存関係の間で直接結合を使用するかどうかを切り替えることができます。このオプションは、構築中のオブジェクト内のシンボル参照とシンボル定義との間に直接結合を確立しません。
DIRECT mapfile キーワードを使用する。このキーワードは、直接結合する個別のシンボルに対応します。このキーワードは、「SYMBOL_SCOPE/SYMBOL_VERSION 指令」で説明されています。
注 - 環境変数 LD_NODIRECT をヌル以外の値に設定すれば、実行時に直接結合を無効にできます。この環境変数を設定することで、プロセス内のすべてのシンボル結合は、デフォルトの検索モデルを使用して実行されます。
次の節では、直接結合の各メカニズムの使用方法について説明します。
-B direct オプションは、どの動的オブジェクトに対しても直接結合を有効にする、もっとも簡単なメカニズムを提供します。このオプションは、どの依存関係にも、また作成中のオブジェクト内に、直接結合を確立します。
前の例で使用されたコンポーネントから、直接結合されたオブジェクトである W.so.2 を作成できます。
$ cc -o W.so.2 -G -Kpic W.c -R. -Bdirect w.so.1 $ cc -o prog2 -R. main.c W.so.2 X.so.1
直接結合の情報は、W.so.2 内にあるシンボル情報セクション (.SUNW_syminfo) に保持されます。このセクションは elfdump(1) を使用すると参照できます。
$ elfdump -y W.so.2 [6] DB <self> a [7] DBL [1] w.so.1 b
文字「DB」は、関連シンボルに対する直接結合が記録されたことを示しています。関数 a() は、格納するオブジェクト W.so.2 に結合されています。関数 b() は、依存関係 w.so.1 に直接結合されています。文字「L」は、依存関係 w.so.1 が遅延読み込みされることも示しています。
W.so.2 に確立された直接結合は、LD_DEBUG 環境を使用すると確認できます。detail トークンは追加情報を結合診断に追加します。W.so.2 の場合、このトークンは結合が直接的であることを示します。detail トークンは、結合アドレスに関する追加情報も提供します。単純化するため、このアドレス情報は、次の例から生成される出力から省略されました。
$ LD_DEBUG=symbols,bindings,detail prog2 ..... 18452: symbol=a; lookup in file=./W.so.2 [ ELF ] 18452: binding file=./W.so.2 to file=./W.so.2: symbol `a' (direct) 18452: symbol=b; lookup in file=./w.so.1 [ ELF ] 18452: binding file=./W.so.2 to file=./w.so.1: symbol `b' (direct)
lari(1) ユーティリティーは直接結合情報を表示することもできます。
$ lari prog2 [2:2ESD]: a(): ./W.so.2 [2:0]: a(): ./X.so.1 [2:2ED]: b(): ./w.so.1 [2:0]: b(): ./x.so.1
文字「D」は、W.so.2 によって定義された関数 a() が直接結合されていることを示しています。同様に、w.so.1 で定義された関数 b() は直接結合されています。
注 - 関数 a() で W.so.2 を W.so.2 に直接結合すると、W.so.2 を構築するときに -B symbolic オプションを使用した場合と類似の効果が生まれます。ただし、-B symbolic オプションでは、内部的に解決できる a() などの参照がリンク編集時に終了処理されることになります。このシンボルの解決では、実行時に解決する結合が残りません。
-B symbolic 結合とは異なり、-B direct では実行時に解決する結合が残ります。このため、この結合は明示的な割り込みによって上書きしたり、環境変数 LD_NODIRECT を非ヌル値に設定することによって無効化したりすることができます。
複雑なオブジェクトを読み込むときに発生する実行時再配置のオーバーヘッドを削減するために、多くの場合、シンボリック結合が採用されてきました。直接結合は、まったく同じシンボル結合を確立するために使用できます。ただし、各直接結合を作成するために実行時再配置が引き続き必要です。直接結合にはシンボリック結合より多くのオーバーヘッドが発生しますが、柔軟性は向上します。
-z direct オプションを使用すると、リンク編集コマンド行のオプションに従うどのような依存関係に対しても直接結合を確立できるメカニズムが提供されます。-B direct オプションとは異なり、構築中のオブジェクト内に、直接結合は確立されません。
このオプションは、割り込まれるように設計されたオブジェクトを作成する場合に適しています。たとえば、共有オブジェクトは、いくつかのデフォルト (フォールバック) インタフェースを持つように設計される場合があります。アプリケーションは、アプリケーション定義を実行時に結合するために、自由にこれらのインタフェースを独自に定義できます。アプリケーションが共有オブジェクトのインタフェースに割り込めるようにするには、-B direct オプションではなく、-z direct オプションを使用して共有オブジェクトを作成します。
-z direct オプションは、1 つまたは複数の依存関係に対する直接結合を選択する場合にも有効です。-z nodirect オプションを使用すると、リンク編集で指定される依存関係の間で、直接結合の使用を切り替えることができます。
前の例で使用されたコンポーネントから、直接結合されたオブジェクトである X.so.2 を作成できます。
$ cc -o X.so.2 -G -Kpic X.c -R. -zdirect x.so.1 $ cc -o prog3 -R. main.c W.so.2 X.so.2
直接結合情報は、elfdump(1) で表示できます。
$ elfdump -y X.so.2 [6] D <self> a [7] DB [1] x.so.1 b
関数 b() は、依存関係 x.so.1 に直接結合されています。関数 a() は、オブジェクト X.so.2 と潜在的な直接結合 (「 D」) を持つように定義されていますが、直接結合は確立されません。
実行時の結合を確認するために、LD_DEBUG 環境変数を使用できます。
$ LD_DEBUG=symbols,bindings,detail prog3 ..... 06177: symbol=a; lookup in file=prog3 [ ELF ] 06177: symbol=a; lookup in file=./W.so.2 [ ELF ] 06177: binding file=./X.so.2 to file=./W.so.2: symbol `a' 06177: symbol=b; lookup in file=./x.so.1 [ ELF ] 06177: binding file=./X.so.2 to file=./x.so.1: symbol `b' (direct)
lari(1) ユーティリティーは直接結合情報を表示することもできます。
$ lari prog3 [2:2ESD]: a(): ./W.so.2 [2:0]: a(): ./X.so.2 [2:1ED]: b(): ./w.so.1 [2:1ED]: b(): ./x.so.1
W.so.2 で定義された関数 a() は、X.so.2 で作成されたデフォルトのシンボル参照を引き続き満たします。しかし、x.so.1 で定義された関数 b() は、X.so.2 で作成された参照から直接結合されています。
DIRECT mapfile キーワードは、個々のシンボルに対して直接結合を確立する手段を提供します。このメカニズムは、特別なリンク編集のシナリオを対象としています。
前の例で使用されたコンポーネントから、関数 main() は外部関数 W() と X() を参照します。これらの関数の結合はデフォルトの検索モデルに従います。
$ LD_DEBUG=symbols,bindings prog3 ..... 18754: symbol=W; lookup in file=prog3 [ ELF ] 18754: symbol=W; lookup in file=./W.so.2 [ ELF ] 18754: binding file=prog3 to file=./W.so.2: symbol `W' ..... 18754: symbol=X; lookup in file=prog3 [ ELF ] 18754: symbol=X; lookup in file=./W.so.2 [ ELF ] 18754: symbol=X; lookup in file=./X.so.2 [ ELF ] 18754: binding file=prog3 to file=./X.so.2: symbol `X'
直接結合が関数 W() と X() に対して確立されるように、prog3 は DIRECT mapfile キーワードを使用して再構築できます。
$ cat mapfile $mapfile_version 2 SYMBOL_SCOPE { global: W { FLAGS = EXTERN DIRECT }; X { FLAGS = EXTERN DIRECT }; }; $ cc -o prog4 -R. main.c W.so.2 X.so.2 -Mmapfile
実行時の結合を確認するために、LD_DEBUG 環境変数を使用できます。
$ LD_DEBUG=symbols,bindings,detail prog4 ..... 23432: symbol=W; lookup in file=./W.so.2 [ ELF ] 23432: binding file=prog4 to file=./W.so.2: symbol `W' (direct) 23432: symbol=X; lookup in file=./X.so.2 [ ELF ] 23432: binding file=prog4 to file=./x.so.2: symbol `X' (direct)
lari(1) ユーティリティーは直接結合情報を表示することもできます。しかしこの場合、関数 W() と X() は多重定義されていません。このためデフォルトでは、lari にはこれらの関数が興味深いものであることはわかりません。すべてのシンボル情報を表示するために、-a オプションを使用する必要があります。
$ lari -a prog4 .... [1:1ED]: W(): ./W.so.2 ..... [2:1ED]: X(): ./X.so.2 .....
注 - W.so.2 と X.so.1 に対する同じ直接結合は、-B direct オプションまたは -z direct オプションを使用して prog4 を構築することで作成できます。この例の唯一の目的は、mapfile キーワードがどのように使用できるかを示すことです。