Go to main content
Oracle® Solaris 11.3 リンカーとライブラリガイド

印刷ビューの終了

更新: 2015 年 10 月
 
 

オブジェクト機能のシンボル機能への変換

理想は、コンパイラがシンボル機能で識別されるオブジェクトを生成できることです。コンパイラがシンボル機能を解決できない場合は、リンカーが解決します。

オブジェクト機能を定義している再配置可能オブジェクトは、リンカーを使用してシンボル機能を定義する再配置可能オブジェクトに変換できます。リンカーの –z symbolcap オプションを使用すると、機能データセクションがすべて変換されて、シンボル機能が定義されます。オブジェクト内のすべての大域関数は局所関数に変換され、シンボル機能に関連付けられます。初期化された大域データ項目は局所データ項目に変換され、シンボル機能に関連付けられます。変換されたこれらのシンボルには、オブジェクト機能グループの一部として指定された機能識別子が追加されます。機能識別子が定義されていない場合は、デフォルトのグループ名が追加されます。

オリジナルの大域関数または初期化されたデータ項目のそれぞれに対して、大域参照が作成されます。この参照は再配置要件に関連付けられており、動的オブジェクトを作成するためにこのオブジェクトを最終的に結合するときに、デフォルトの大域シンボルに結合できます。


注 -  –z symbolcap オプションは、オブジェクト機能セクションを含んでいるオブジェクトだけに適用されます。このオプションは、すでにシンボル機能を含んでいる再配置可能オブジェクト、オブジェクトおよびシンボルの機能を含む再配置可能オブジェクト、または機能を含まない再配置可能オブジェクトに影響しません。この設計により、複数のオブジェクトがリンカーによって結合でき、オブジェクト機能を含むオブジェクトだけがこのオプションの影響を受けます。

次の例では、x86 再配置可能オブジェクトは 2 つの大域関数 foo() および bar() を含んでいます。このオブジェクトは MMXSSE のハードウェア機能を要求するようにコンパイルされました。これらの例では、機能グループは機能識別子エントリを使用して名前が付けられました。この識別子名は変換されたシンボル名に追加されます。この明示的な識別子がないと、リンカーはデフォルトの機能グループ名を追加します。

$ 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