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

印刷ビューの終了

更新: 2014 年 7 月
 
 

明示的な割り込みの定義

デフォルトの検索モデルでは、同じ名前のシンボルのインスタンスが、同じ名前の後のインスタンスに割り込む可能性があります。明示的なラベル付けをしなくても割り込みは発生するため、1 つのシンボル定義がすべての参照から結合されます。この暗黙の割り込みはシンボル検索の結果として起こるもので、実行時リンカーに指定された明示的な命令によるものではありません。この暗黙の割り込みは直接結合によって回避できます。

直接結合は、関連するシンボル定義に対する直接のシンボル参照を解決する働きをしますが、明示的な割り込みは直接結合の検索の前に処理されます。このため、直接結合の環境であっても、割り込み処理を設計でき、直接結合の関連付けに割り込みを期待できます。割り込み処理は、次の方法を利用して明示的に定義できます。

  • LD_PRELOAD 環境変数を使用。

  • リンカーの –z interpose オプションを使用。

  • INTERPOSE mapfile キーワードを使用。

  • singleton シンボル定義の結果として。

LD_PRELOAD 環境変数の割り込み機能と –z interpose オプションが、しばらく前から利用可能です。実行時割り込みを参照してください。これらのオブジェクトは割り込み処理であると明示的に定義されているため、実行時リンカーは直接結合を処理する前にこれらのオブジェクトを検査します。

共有オブジェクトに対して確立された割り込みは、その動的オブジェクトのすべてのインタフェースに適用されます。LD_PRELOAD 環境変数を使用してオブジェクトがロードされたときに、このオブジェクトの割り込みが確立されます。オブジェクトの割り込みは、–z interpose オプションで作成されたオブジェクトが読み込まれたときにも確立されます。このオブジェクトモデルが重要なのは、特別なハンドル RTLD_NEXT を持つ dlsym(3C) などの技術が使用されたときです。割り込むオブジェクトは、次のオブジェクトの一貫したビューを常に持つべきです。

動的実行可能ファイルは、INTERPOSE mapfile キーワードを使用して個々の割り込みシンボルを定義できるという点で柔軟性が増します。動的実行可能ファイルはプロセスにロードされる最初のオブジェクトであるため、次のオブジェクトの実行可能ファイルのビューは常に一貫したものになります。

次の例は、exit() 関数に明示的に割り込みを行うアプリケーションを示しています。

$ cat mapfile
$mapfile_version 2
SYMBOL_SCOPE {
        global:
                exit    { FLAGS = INTERPOSE };
};
$ cc -o prog -M mapfile exit.c a.c b.c ....
$ elfdump -y prog | fgrep exit
[6]  DI          <self>         exit

文字「I」は、このシンボルの割り込み特性を表しています。おそらく、この exit() 関数の実装では、システム関数 _exit() が直接参照されるか、または RTLD_NEXT ハンドルを持つ dlsym() を使ってシステム関数 exit() に達するまで呼び出しが続けられると考えられます。

最初は、–z interpose オプションを使ってこのオブジェクトを特定することを考えてはどうでしょうか。ただし、この手法は、アプリケーションによってエクスポートされたすべてのインタフェースが割り込み処理として機能するため、かなりの重量になります。より適切な代替方法は、–z interpose オプションを使用するとともに、割り込み処理を除く、アプリケーションで提供されたすべてシンボルをローカライズすることです。

しかし、INTERPOSE mapfile キーワードを使用すると、柔軟性が向上します。このキーワードを使用すると、アプリケーションでいくつかのインタフェースをエクスポートしながら、それらのインタフェースから割り込み処理として機能させるものを選択できます。

STV_SINGLETON 可視性が割り当てられているシンボルには、効果的な割り込みの形態が備わっています。Table 12–23 を参照してください。これらのシンボルは、コンパイルシステムによって、プロセス内の多数のオブジェクトで多重インスタンス化状態になる可能性がある実装に割り当てることができます。singleton シンボルへのすべての参照は、プロセス内で最初に定義された singleton に結合されます。