ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
リンカーとライブラリ Oracle Solaris 10 8/11 Information Library (日本語) |
直接結合は明示的な割り込みで無効にできます。「明示的な割り込みの定義」を参照してください。しかし、明示的な割り込みの確立を制御できない場合があります。
たとえば、直接結合を使用する共有オブジェクトファミリを配布するとします。また、このファミリの共有オブジェクトによって提供されるシンボルに顧客が割り込むことがわかっています。これらの顧客が自身の割り込み要件を明示的に定義しないと、直接結合を使用する共有オブジェクトの再配布によって、その割り込みが損なわれる場合があります。
ユーザーが独自の割り込みルーチンを提供することを期待して、いくつかのデフォルトインタフェースを提供する共有オブジェクトを設計することもできます。
既存のアプリケーションが混乱を起こさないようにするため、1 つまたは複数のインタフェースに明示的に直接結合しない共有オブジェクトを配布できます。
動的オブジェクトへの直接結合は、次のいずれかのオプションを使用すると回避できます。
-B nodirect オプションを使用する。このオプションを使用すると、作成中のオブジェクトが提供するインタフェースに直接結合されません。
NODIRECT mapfile キーワードを使用する。このキーワードを使用すると、個別のシンボルへの直接結合を避けられます。このキーワードは、「SYMBOL_SCOPE/SYMBOL_VERSION 指令」で説明されています。
nodirect とラベルが付けられたインタフェースは、外部オブジェクトから直接結合できません。また、nodirect とラベルが付けられたインタフェースは、同じオブジェクト内から直接結合できません。
次の節では、直接結合回避メカニズムの各使用方法について説明します。
-B nodirect オプションは、どの動的オブジェクトからの直接結合も回避する、もっとも簡単なメカニズムを提供します。このオプションはほかのオブジェクトから、また作成中のオブジェクト内からの直接結合を回避します。
次のコンポーネントを使用して、3 つの共有オブジェクト、A.so.1、O.so.1、およびX.so.1 を作成します。-B nodirect オプションを使用すると、A.so.1 は O.so.1 に直接結合されません。しかし、O.so.1 は、-z direct オプションを使用して X.so.1 への直接結合を引き続き確立できます。
$ cat a.c extern int o(), p(), x(), y(); int a() { return (o() + p() - x() - y()); } $ cat o.c extern int x(), y(); int o() { return (x()); } int p() { return (y()); } $ cat x.c int x() { return (1); } int y() { return (2); } $ cc -o X.so.1 -G -Kpic x.c $ cc -o O.so.1 -G -Kpic o.c -Bnodirect -zdirect -R. X.so.1 $ cc -o A.so.1 -G -Kpic a.c -Bdirect -R. O.so.1 X.so.1
A.so.1 および O.so.1 のシンボル情報は、elfdump(1) で参照できます。
$ elfdump -y A.so.1 [1] DBL [3] X.so.1 x [5] DBL [3] X.so.1 y [6] DL [1] O.so.1 o [9] DL [1] O.so.1 p $ elfdump -y O.so.1 [3] DB [0] X.so.1 x [4] DB [0] X.so.1 y [6] N o [7] N p
文字「N」は、関数 o() および p() に直接結合が許可されていないことを示しています。A.so.1 が -B direct オプションによって直接結合を要求したとしても、関数 o() および p() に直接結合は確立されません。O.so.1 は引き続き、-z direct オプションを使用して依存関係 X.so.1 への直接結合を要求できます。
Oracle Solaris ライブラリ libproc.so.1 は、-B nodirect オプションを使って作成されます。このライブラリのユーザーは、多くの libproc 関数に対して独自のコールバックインタフェースを用意することが求められています。libproc の依存関係から libproc 関数への参照は、いずれかのユーザー定義 (このような定義がある場合) に結合する必要があります。
NODIRECT mapfile キーワードは、個々のシンボルへの直接結合を回避する手段を提供します。このキーワードは、-B nodirect オプションよりも詳細に直接結合の回避を制御できます。
前の例で使用されたコンポーネントから、O.so.2 は、関数 o() に直接接続しないように作成できます。
$ cat mapfile $mapfile_version 2 SYMBOL_SCOPE { global: o { FLAGS = NODIRECT }; }; $ cc -o O.so.2 -G -Kpic o.c -Mmapfile -zdirect -R. X.so.1 $ cc -o A.so.2 -G -Kpic a.c -Bdirect -R. O.so.2 X.so.1
A.so.2 および O.so.2 のシンボル情報は、elfdump(1) で参照できます。
$ elfdump -y A.so.2 [1] DBL [3] X.so.1 x [5] DBL [3] X.so.1 y [6] DL [1] O.so.1 o [9] DBL [1] O.so.1 p $ elfdump -y O.so.1 [3] DB [0] X.so.1 x [4] DB [0] X.so.1 y [6] N o [7] D <self> p
O.so.1 は、関数 o() が直接結合できないことを宣言するだけです。このため A.so.2 は、O.so.1 内の関数 p() に直接結合できます。
Oracle Solaris ライブラリ内にあるいくつかの個別インタフェースは、直接結合できないように定義されています。データ項目 errno はその 1 例です。このデータ項目は libc.so.1 で定義されています。このデータ項目は、ヘッダーファイル stdio.h をインクルードすることで参照できます。しかし、多くのアプリケーションでは独自の errno を定義するように指導されているのが一般的でした。libc.so.1 で定義された errno に直接結合するシステムライブラリファミリが配布された場合、これらのアプリケーションの機能が損なわれることになります。
直接結合しないように定義された別のインタフェースファミリには、malloc(3C) ファミリがあります。malloc() ファミリは、ユーザーアプリケーション内に頻繁に実装される別のインタフェースセットです。これらのユーザー実装はシステム定義に割り込むことを意図しています。
注 - Oracle Solaris OS には、代替の malloc() 実装を提供する、さまざまなシステム割り込みライブラリが備わっています。また各実装は、プロセス内で使用される唯一の実装であることが期待されます。すべての malloc() 割り込みライブラリは -z interpose オプションを指定して作成されています。libc.so.1 内の malloc() ファミリは、直接結合しないようにラベル付けされているので、このオプションは必ずしも必要ではありません。
しかし、割り込み処理を作成するための先例とするため、割り込みライブラリは -z interpose を指定して作成されました。この明示的な割り込みには、libc.so.1 内に確立された直接結合の回避定義に対する不都合な相互作用はありません。
STV_SINGLETON 可視性が割り当てられているシンボルは、直接結合できません。表 7-20 を参照してください。これらのシンボルは、コンパイルシステムによって、プロセス内のいくつかのオブジェクトで多重インスタンス化状態になる可能性がある実装に割り当てることができます。singleton シンボルへのすべての参照は、プロセス内で最初に定義された singleton に結合されます。