理想は、コンパイラがシンボル機能で識別されるオブジェクトを生成できることです。コンパイラがシンボル機能を解決できない場合は、リンカーが解決します。
オブジェクト機能を定義している再配置可能オブジェクトは、リンカーを使用してシンボル機能を定義する再配置可能オブジェクトに変換できます。リンカーの –z symbolcap オプションを使用すると、機能データセクションがすべて変換されて、シンボル機能が定義されます。オブジェクト内のすべての大域関数は局所関数に変換され、シンボル機能に関連付けられます。初期化された大域データ項目は局所データ項目に変換され、シンボル機能に関連付けられます。変換されたこれらのシンボルには、オブジェクト機能グループの一部として指定された機能識別子が追加されます。機能識別子が定義されていない場合は、デフォルトのグループ名が追加されます。
オリジナルの大域関数または初期化されたデータ項目のそれぞれに対して、大域参照が作成されます。この参照は再配置要件に関連付けられており、動的オブジェクトを作成するためにこのオブジェクトを最終的に結合するときに、デフォルトの大域シンボルに結合できます。
次の例では、x86 再配置可能オブジェクトは 2 つの大域関数 foo() および bar() を含んでいます。このオブジェクトは MMX と SSE のハードウェア機能を要求するようにコンパイルされました。これらの例では、機能グループは機能識別子エントリを使用して名前が付けられました。この識別子名は変換されたシンボル名に追加されます。この明示的な識別子がないと、リンカーはデフォルトの機能グループ名を追加します。
$ elfdump -H foo.o Capabilities Section: .SUNW_cap Object Capabilities: index tag value [0] CA_SUNW_ID sse,mmx [1] CA_SUNW_HW_1 0x840 [ SSE MMX ] $ elfdump -s foo.o | egrep "foo|bar" [25] 0 0x21 FUNC GLOB D 0 .text foo [26] 0x24 0x1e FUNC GLOB D 0 .text bar $ elfdump -r foo.o | fgrep foo R_386_PLT32 0x38 .rel.text foo
これで、この再配置可能オブジェクトはシンボル機能の再配置可能オブジェクトに変換できます。
$ ld -r -o foo.1.o -z symbolcap foo.o $ elfdump -H foo.1.o Capabilities Section: .SUNW_cap Symbol Capabilities: index tag value [1] CA_SUNW_ID sse,mmx [2] CA_SUNW_HW_1 0x840 [ SSE MMX ] Symbols: index value size type bind oth ver shndx name [25] 0 0x21 FUNC LOCL D 0 .text foo%sse,mmx [26] 0x24 0x1e FUNC LOCL D 0 .text bar%sse,mmx $ elfdump -s foo.1.o | egrep "foo|bar" [25] 0 0x21 FUNC LOCL D 0 .text foo%sse,mmx [26] 0x24 0x1e FUNC LOCL D 0 .text bar%sse,mmx [37] 0 0 FUNC GLOB D 0 UNDEF foo [38] 0 0 FUNC GLOB D 0 UNDEF bar $ elfdump -r foo.1.o | fgrep foo R_386_PLT32 0x38 .rel.text foo
このオブジェクトは、同じ関数 (別のシンボル機能に関連) のインスタンスを含む別のオブジェクトと結合でき、実行可能ファイルまたは共有オブジェクトを作成できるようになりました。また、シンボル機能と関連付けられていない、各機能ファミリの先頭となる各関数のデフォルトインスタンスが提供される必要があります。このデフォルトのインスタンスはすべての外部参照に対応しており、どのシステムでも関数のインスタンスが確実に使用できるようになります。
実行時、foo() と bar() へのすべての参照は、先頭のインスタンスに向けられます。ただし、システムが適切な機能に対応している場合、実行時リンカーは最適なシンボル機能インスタンスを選択します。
アーカイブライブラリには通常、再配置可能オブジェクトの集合が含まれます。リンカーは、個々の再配置可能なオブジェクトを抽出して、未解決のシンボル参照を解決できます。アーカイブ処理を参照してください。
機能再配置可能オブジェクトのファミリがアーカイブに追加された場合、先頭機能シンボルのすべての参照は、そのシンボルを定義する汎用再配置可能オブジェクトだけを抽出します。ほかの機能オブジェクトは抽出されません。
アーカイブライブラリを使用して機能オブジェクトを配備する必要がある場合、単一の機能ファミリ再配置オブジェクトを作成する必要があります。すべての機能オブジェクト、および機能の先頭のシンボルを含んだすべての汎用オブジェクトを 1 つの再配置可能オブジェクトに組み合わせます。機能ファミリコレクション全体を含むこの単一オブジェクトを、アーカイブに追加します。
$ ld -r -o all.foo.o foo.o foo.1.o foo.2.o .... $ ar -cr libfoo.o all.foo.o