補助フィルタを生成するには、まずフィルタ処理を適用する「フィルティー」を定義する必要があります。次の例では、シンボル foo を提供する「フィルティー」filtee.so.1 を構築します。
$ cat filtee.c
char * foo()
{
return("defined in filtee");
}
$ cc -o filtee.so.1 -G -K pic filtee.c
|
共有オブジェクトによって提供されるすべてのインタフェースを補助フィルタとして宣言するには、リンカーの -f フラグを使用してその共有オブジェクトを補助フィルタとして定義します。
次の例では、共有オブジェクト filter.so.1 が補助フィルタとして定義されています。この共有オブジェクトは、シンボル foo と bar を提供し、それ自体が「フィルティー」filtee.so.1 の補助フィルタであることを示しています。この例では、コンパイラドライバが -f
オプションを解釈しないように、環境変数 LD_OPTIONS
が使用されています。
$ cat filter.c
char * bar = "defined in filter";
char * foo()
{
return ("defined in filter");
}
$ LD_OPTIONS='-f filtee.so.1' \
cc -o filter.so.1 -G -K pic -h filter.so.1 -R. filter.c
$ elfdump -d filter.so.1 | egrep "SONAME|AUXILIARY"
[2] SONAME 0xee filter.so.1
[3] AUXILIARY 0xfb filtee.so.1
|
動的実行可能ファイルまたは共有オブジェクトを作成するために補助フィルタ filter.so.1 を参照する場合、リンカーはフィルタのシンボルテーブルの情報を使用してシンボル解決を行います。しかし、実行時にフィルタのシンボルを参照すると、「フィルティー」filtee.so.1 が検索されます。この「フィルティー」が見つかると、実行時リンカーは、この「フィルティー」を使用して、filter.so.1 によって定義されたすべてのシンボルを解決します。この「フィルティー」が見つからないか、あるいは「フィルティー」内にフィルタからのシンボルが見つからない場合は、フィルタ内の元のシンボルが使用されます。
たとえば、次の動的実行可能プログラム prog は、シンボル foo と bar を参照します。これらのシンボルは、リンク編集中にフィルタ filter.so.1 から解決されます。prog を実行すると、foo が、フィルタ filter.so.1 からではなく、「フィルティー」filtee.so.1 から取得されます。しかし、bar はフィルタ filter.so.1 から取得されます。これは、「フィルティー」filtee.so.1 内にこのシンボルの代替定義が存在しないためです。
$ cat main.c
extern char * bar, * foo();
main()
{
(void) printf("foo is %s: bar is %s\n", foo(), bar);
}
$ cc -o prog main.c -R. filter.so.1
$ prog
foo is defined in filtee: bar is defined in filter
|
これらの例では、「フィルティー」filtee.so.1 がフィルタに一意に関連付けられています。このため、prog を実行した結果読み込まれる可能性があるほかのオブジェクトからのシンボル参照を満たすために使用することができません。
補助フィルタは、既存の共有オブジェクトの代替インタフェースを定義するメカニズムとなります。このメカニズムは Solaris オペレーティング環境で使用されて、プラットフォーム固有の共有オブジェクト内に最適化された機能を提供します。例は、命令セット固有の共有オブジェクトと システム固有の共有オブジェクトを参照してください。
環境変数 LD_NOAUXFLTR を設定して、実行時リンカーの補助フィルタ処理を無効にすることができます。補助フィルタはプラットフォーム固有の最適化に使用されることが多いので、「フィルティー」の使用およびそれらの性能インパクトを評価する場合にこのオプションが便利です。