リンカーとライブラリ

標準フィルタの生成

標準フィルタを生成するには、まずフィルティー libbar.so.1 を定義し、それに対してこのフィルタ手法を適用します。このフィルティーは、いくつかの再配置可能オブジェクトから構築される場合があります。次の例では、これらのオブジェクトの 1 つは、ファイル bar.c から発生し、シンボル foobar を与えます。


$ cat bar.c
char * bar = "bar";

char * foo()
{
        return("defined in bar.c");
}
$ cc -o libbar.so.1 -G -K pic .... bar.c ....

次の例では、標準フィルタ libfoo.so.1 は、シンボル foobar に対して生成されて、フィルティー libbar.so.1 への関連付けを示します。環境変数 LD_OPTIONS は、このコンパイラドライバが -f オプションをそれ自体のオプションの 1 つとして解釈しないようにするために使用されています。


$ cat foo.c
char * bar = 0;

char * foo(){}

$ LD_OPTIONS='-F libbar.so.1' \
cc -o libfoo.so.1 -G -K pic -h libfoo.so.1 -R. foo.c
$ ln -s libfoo.so.1 libfoo.so
$ dump -Lv libfoo.so.1 | egrep "SONAME|FILTER"
[1]     SONAME   libfoo.so.1
[2]     FILTER   libbar.so.1

リンカーは、標準フィルタ libfoo.so.1 を参照して動的実行可能ファイルまたは共有オブジェクトを作成する場合、シンボル解決中にフィルタのシンボルテーブルからの情報を使用します。詳細については、シンボル解析を参照してください。

実行時に、フィルタのシンボルを参照すると、必ずフィルティー libbar.so.1 がさらに読み込まれます。実行時リンカーは、このフィルティーを使用して、libfoo.so.1 によって定義されたシンボルを解釈処理します。

たとえば、次の動的実行可能ファイル prog は、シンボル foobar を参照します。これらのシンボルは、フィルタ libfoo.so.1 からのリンク編集中に解釈処理されます。


$ cat main.c
extern char * bar, * foo();

main()
{
        (void) printf("foo() is %s: bar=%s\n", foo(), bar);
}
$ cc -o prog main.c -R. -L. -lfoo
$ prog
foo() is defined in bar.c: bar=bar

動的実行可能ファイル prog を実行すると、関数 foo() とデータ項目 bar が、フィルタ libfoo.so.1 からではなく、フィルティー libbar.so.1 から取得されます。

この例では、フィルティー libbar.so.1 がフィルタ libfoo.so.1 に一意に関連付けられています。このため、prog を実行した結果読み込まれる可能性がある他のオブジェクトからのシンボル参照を満たすために使用することができません。

標準フィルタは、既存の共有オブジェクトのサブセットインタフェース、または多数の既存の共有オブジェクトに及ぶインタフェースグループを定義するためのメカニズムとなります。Solaris オペレーティング環境では、いくつかのフィルタが使用されます。

/usr/lib/libsys.so.1 フィルタは、標準 C ライブラリ /usr/lib/libc.so.1 のサブセットを提供します。 このサブセットは、準拠するアプリケーションによってインポートしなければならない C ライブラリ内の ABI に準拠する関数とデータ項目を表わします。

/usr/lib/libdl.so.1 フィルタは、実行時リンカー自体へのユーザーインタフェースを定義します。このインタフェースは、コンパイル環境で (libdl.so.1 から) 参照されるシンボルと、実行時環境内で (ld.so.1 から) 作成される実際の実装結合間の抽象化を提供します。

/usr/lib/libxnet.so.1 フィルタは、複数のフィルティーを使用します。このライブラリは、/usr/lib/libsocket.so.1/usr/lib/libnsl.so.1、および /usr/lib/libc.so.1 から、ソケットと XTI インタフェースを提供します。

標準フィルタ内のコードは実行時に参照されないため、このフィルタ内に定義された関数に内容を加えても意味がありません。フィルタコードが再配置を必要とする場合がありますが、実行時にそのフィルタを処理すると不要なオーバーヘッドが生じます。関数は空のルーチンとして定義するか、直接 mapfile から定義してください。追加シンボルの定義を参照してください。

フィルタ内にデータシンボルを生成するときは、データ項目を必ず初期設定して、動的実行可能ファイルから参照されるように保証する必要があります。

リンカーによって実行される、より複雑なシンボル解釈処理の中には、シンボルサイズを含むシンボルの属性に関する知識を必要とするものがあります。詳細については、シンボル解析を参照してください。このため、フィルタ内のシンボルの属性がフィルティー内のシンボルの属性と一致するようにシンボルを生成する必要があります。これにより、リンク編集処理では、実行時に使用されるシンボル定義と互換性のある方法でフィルタが解析されます。


注 –

リンカーは、最初に入力された再配置可能ファイルの ELF クラスを使用して、作成するオブジェクトのクラスを管理します。64 ビットフィルタを mapfile だけから作成するには、リンカーの -64 オプションを使用します。