システム機能は、実行中のシステムを記述する機能です。プラットフォーム名およびマシンハードウェア名は、それぞれ –i オプションと –m オプションを使用すると、uname(1)で表示できます。システムのハードウェア機能は、–v オプションを使用してisainfo(1)で表示できます。実行時にオブジェクトのプラットフォーム名、マシンハードウェア名、およびハードウェア機能要件がシステム機能と比較され、オブジェクトをロードできるかどうか、またはオブジェクト内のシンボルを使用できるかどうかが判定されます。
オブジェクト機能は、オブジェクトに関連する機能です。これらの機能はオブジェクト全体の要件を定義します。プラットフォーム、マシン、およびハードウェア機能は、実行時にオブジェクトをロードできるかどうかを制御します。あるオブジェクトが、システムで満たすことができない機能を要求している場合、そのオブジェクトは実行時に読み込めません。機能を使用すると任意のオブジェクトから複数のインスタンスを作成でき、各インスタンスはオブジェクト要件に一致するシステムに最適化されます。実行時リンカーは、オブジェクトの機能要件をシステムが提供する機能と比較することで、このようなオブジェクトインスタンスファミリの中から最適なインスタンスを透過的に選択します。
シンボル機能は、オブジェクト内の各関数または初期化されたデータ項目に関連する機能です。プラットフォーム、マシン、およびハードウェア機能は、オブジェクト内の 1 つまたは複数のシンボルの要件を定義し、実行時にシンボルを使用できるかどうかを制御します。シンボル機能によって、1 つの関数の複数のインスタンスが 1 つのオブジェクト内に存在できます。関数の各インスタンスは、別々の機能を持つシステムに対して最適化できます。また、1 つの初期化されたデータ項目の複数のインスタンスも 1 つのオブジェクト内に存在できます。データの各インスタンスはシステム固有のデータを定義できます。シンボルのインスタンスが、システムによって満たすことができない機能を要求している場合、そのシンボルインスタンスは実行時に使用できません。代わりに、同じシンボル名の代替インスタンスを使用する必要があります。シンボル機能では、単一のオブジェクトをさまざまな機能のシステムで使用できるようにオブジェクトを構築できます。機能ファミリは、機能に対応できるシステム向けの最適化されたインスタンスと、機能が比較的低いほかのシステム向けのより汎用的なインスタンスを提供できます。初期化されたデータ項目のファミリはシステム固有データを提供できます。実行時リンカーは、シンボルの機能要件をシステムが提供する機能と比較することで、このようなシンボルインスタンスファミリの中から最適なインスタンスを透過的に選択します。
オブジェクトとシンボルの機能は、現在動作中のシステムに対して最適なオブジェクト、およびオブジェクト内の最適なシンボルを選択できます。オブジェクトとシンボルの機能はオプションであり、互いに独立しています。ただし、シンボル機能を定義しているオブジェクトがオブジェクト機能を定義してもかまいません。この場合、機能シンボルファミリには、オブジェクト機能を満たすシンボルの 1 つのインスタンスが伴われることになります。オブジェクトの機能が存在しない場合、機能シンボルファミリには、機能を要求しないシンボルの 1 つのインスタンスが伴われることになります。指定されたシステムに適合できる機能インスタンスがない場合、このシンボルインスタンスによってデフォルト実装が提供されます。
次の x86 の例は、foo.o のオブジェクト機能を示します。これらの機能はオブジェクト全体に適用されます。この例には、シンボル機能がありません。
$ elfdump -H foo.o Capabilities Section: .SUNW_cap Object Capabilities: index tag value [0] CA_SUNW_HW_1 0x840 [ SSE MMX ]
次の x86 の例は、bar.o のシンボル機能を示します。これらの機能は個々の関数 foo() および bar() に適用されます。各シンボルのインスタンスは 2 つ存在し、それぞれのインスタンスは別々の機能セットに割り当てられています。この例には、オブジェクト機能がありません。
$ elfdump -H bar.o Capabilities Section: .SUNW_cap Symbol Capabilities: index tag value [1] CA_SUNW_HW_1 0x40 [ MMX ] Symbols: index value size type bind oth ver shndx name [25] 0 0x21 FUNC LOCL D 0 .text foo%mmx [26] 0x24 0x1e FUNC LOCL D 0 .text bar%mmx Symbol Capabilities: index tag value [3] CA_SUNW_HW_1 0x800 [ SSE ] Symbols: index value size type bind oth ver shndx name [33] 0x44 0x21 FUNC LOCL D 0 .text foo%sse [34] 0x68 0x1e FUNC LOCL D 0 .text bar%sse
機能定義には、オブジェクトの要件、またはオブジェクト内の各シンボルの要件を特定できる多くの組み合わせが用意されています。
次のセクションでは、機能の定義方法とリンカーによる使用方法について説明します。
オブジェクトのプラットフォームまたはマシン機能では、オブジェクトまたはオブジェクト内の特定のシンボルが実行できるシステムのプラットフォーム名またはマシンハードウェア名を指定します。複数のプラットフォームまたはマシン機能を定義できます。これらの指定はもっとも具体的であり、ほかの機能タイプに優先します。これらの指定は特殊なシステムライブラリで使用できますが、通常はハードウェア機能の方がより柔軟に機能インスタンスを作成する手段を提供します。
システムのプラットフォーム名は、ユーティリティーuname(1)に –i オプションを付けて実行すると表示できます。プラットフォーム機能要件は次の mapfile 構文を使用すると定義できます。
$mapfile_version 2 CAPABILITY { PLATFORM = platform_name...; PLATFORM += platform_name...; PLATFORM -= platform_name...; };
システムのマシンハードウェア名は、ユーティリティーuname(1)に –m オプションを付けて実行すると表示できます。マシン機能要件は次の mapfile 構文を使用すると定義できます。
$mapfile_version 2 CAPABILITY { MACHINE = machine_name...; MACHINE += machine_name...; MACHINE -= machine_name...; };
PLATFORM または MACHINE 属性は、スペースで区切られた 1 つまたは複数のプラットフォーム名またはマシン名で修飾されます。「+=」形式の代入を使用すると、入力オブジェクトで指定されたプラットフォーム機能またはマシン機能に追加できます。「=」形式はこれらをオーバーライドします。「-=」形式の代入を使用すると、出力オブジェクトからプラットフォーム機能またはマシン機能を削除できます。
次の SPARC の例では、オブジェクト foo.so.1 を sun4v マシンハードウェア名に固有であることを指定します。
$ cat mapfile $mapfile_version 2 CAPABILITY { MACHINE = sun4v; }; $ cc -o foo.so.1 -G -K pic -Mmapfile foo.c -lc $ elfdump -H foo.so.1 Capabilities Section: .SUNW_cap Object Capabilities: index tag value [0] CA_SUNW_MACH sun4v
再配置可能オブジェクトはプラットフォーム機能またはマシン機能を定義できます。これらの機能がまとめられて、作成中のオブジェクトの最終的な機能要件が定義されます。
オブジェクトのプラットフォーム機能またはマシン機能は、「=」形式の代入を使用すると mapfile から明示的に制御でき、入力の再配置可能オブジェクトから指定される可能性のあるプラットフォーム機能またはマシン機能をオーバーライドできます。「=」形式の代入を使用して空の PLATFORM または MACHINE 属性を指定すると、作成中のオブジェクトからプラットフォームまたはマシンのすべての機能要件が削除されます。
動的オブジェクトで定義されたプラットフォームまたはマシンの機能要件は、システムのプラットフォーム名またはマシン名に照らして、実行時リンカーによって検証されます。オブジェクトが使用されるのは、オブジェクトに記録されたプラットフォーム名またはマシン名の 1 つがシステムのプラットフォーム名またはマシン名に一致した場合だけです。
オブジェクトのハードウェア機能は、オブジェクトまたは特定のシンボルを正しく実行するために必要なシステムのハードウェア要件を特定します。この要件の例としては、x86 アーキテクチャーで利用できる MMX または SSE の機能を必要とするコードの特定があります。
ハードウェア機能要件は、次の mapfile 構文を使用して特定できます。
$mapfile_version 2 CAPABILITY { HW = hwcap_flag...; HW += hwcap_flag...; HW -= hwcap_flag...; };
CAPABILITY 指令に対する HW 属性は、ハードウェア機能のシンボル表現である 1 つまたは複数のトークンで修飾されます。「+=」形式の代入を使用すると、入力オブジェクトで指定されたハードウェア機能に追加できます。「=」形式はオーバーライドします。「-=」形式の代入を使用すると、出力オブジェクトからハードウェア機能を削除できます。
SPARC システムでは、ハードウェア機能は sys/auxv_SPARC.h の AV_ の値として定義されます。x86 システムでは、ハードウェア機能は sys/auxv_386.h の AV_ の値として定義されます。
次の x86 の例では、オブジェクト foo.so.1 に必要なハードウェア機能として MMX と SSE が宣言されています。
$ egrep "MMX|SSE" /usr/include/sys/auxv_386.h #define AV_386_MMX 0x0040 #define AV_386_SSE 0x0800 $ cat mapfile $mapfile_version 2 CAPABILITY { HW += SSE MMX; }; $ cc -o foo.so.1 -G -K pic -Mmapfile foo.c -lc $ elfdump -H foo.so.1 Capabilities Section: .SUNW_cap Object Capabilities: index tag value [0] CA_SUNW_HW_1 0x840 [ SSE MMX ]
再配置可能オブジェクトには、ハードウェア機能の値を含めることができます。リンカーは、複数の入力再配置可能オブジェクトからのハードウェア機能値を組み合わせます。この結果生じる CA_SUNW_HW_1 の値は、関連入力値のビット単位の OR となります。デフォルトでは、これらの値は、mapfile で指定されたハードウェア機能と組み合わせられます。
オブジェクトのハードウェア機能要件は、「=」形式の代入を使用すると mapfile から明示的に制御でき、入力の再配置可能オブジェクトから指定される可能性のあるハードウェア機能をオーバーライドできます。「=」形式の代入を使用して空の HW 属性を指定すると、作成中のオブジェクトからハードウェアのすべての機能要件が削除されます。
次の例では、入力の再配置可能オブジェクト foo.o で定義されたハードウェア機能のデータが出力ファイル bar.o に含まれないように隠されています。
$ elfdump -H foo.o Capabilities Section: .SUNW_cap Object Capabilities: index tag value [0] CA_SUNW_HW_1 0x840 [ SSE MMX ] $ cat mapfile $mapfile_version 2 CAPABILITY { HW = ; }; $ ld -o bar.o -r -Mmapfile foo.o $ elfdump -H bar.o $
動的オブジェクトが定義したハードウェア機能要件は、システムが提供するハードウェア機能に照らして、実行時リンカーによって検証されます。ハードウェア機能要件の一部を満足できない場合、そのオブジェクトは実行時に読み込みされません。たとえば、SSE 機能がプロセスで利用できない場合、ldd(1)は次のエラーを示します。
$ ldd prog foo.so.1 => ./foo.so.1 - hardware capability unsupported: 0x800 [ SSE ] ....
別々のハードウェア機能を利用する動的オブジェクトの複数のインスタンスは、フィルタを使用することによって、柔軟な実行時環境を提供できます。機能固有の共有オブジェクトを参照してください。
ハードウェア機能は、1 つのオブジェクト内の個々の関数の機能を指定するためにも使用できます。この場合、実行時リンカーは現在のシステム機能に基づいて使用する最適な関数を選択できます。シンボル機能関数ファミリの作成を参照してください。
オブジェクトのソフトウェア機能は、プロセスのデバッグまたはモニタリングにとって重要なことがあるソフトウェアの特徴を特定します。ソフトウェア機能はプロセスの実行にも影響を与えることができます。現在のところ、オブジェクトによるフレームポインタの使用、およびプロセスアドレス空間の制限に関連したソフトウェア機能のみが存在します。
オブジェクトは、フレームポインタ使用を認識することを示せます。この状態は、フレームポインタを使用中または未使用として宣言することで、修飾されます。
64 ビットのオブジェクトは、実行時に 32 ビットのアドレス空間内で実行しなければならないことを指定できます。
ソフトウェア機能フラグは、sys/elf.h で定義されています。
#define SF1_SUNW_FPKNWN 0x001 #define SF1_SUNW_FPUSED 0x002 #define SF1_SUNW_ADDR32 0x004
これらのソフトウェア機能要件は、次の mapfile 構文を使用して特定できます。
$mapfile_version 2 CAPABILITY { SF = sfcap_flags...; SF += sfcap_flags...; SF -= sfcap_flags...; };
CAPABILITY 指令に対する SF 属性は、トークン FPKNWN、 FPUSED、および ADDR32 のいずれにも割り当てることができます。
再配置可能オブジェクトには、ソフトウェア機能の値を含めることができます。リンカーは、複数の入力再配置可能オブジェクトからのソフトウェア機能値を組み合わせます。ソフトウェア機能は、mapfile も提供されます。デフォルトでは、mapfile のすべての値が、再配置可能オブジェクトで提供される値と組み合わせられます。
オブジェクトのソフトウェア機能要件は、「=」形式の代入を使用すると mapfile から明示的に制御でき、入力の再配置可能オブジェクトから指定される可能性のあるソフトウェア機能をオーバーライドできます。「=」形式の代入を使用して空の HW 属性を指定すると、作成中のオブジェクトからソフトウェアのすべての機能要件が削除されます。
次の例では、入力の再配置可能オブジェクト foo.o で定義されたソフトウェア機能のデータが出力ファイル bar.o に含まれないように隠されています。
$ elfdump -H foo.o Object Capabilities: index tag value [0] CA_SUNW_SF_1 0x3 [ SF1_SUNW_FPKNWN SF1_SUNW_FPUSED ] $ cat mapfile $mapfile_version 2 CAPABILITY { SF = ; }; $ ld -o bar.o -r -Mmapfile foo.o $ elfdump -H bar.o $
2 つのフレームポインタ入力値からの CA_SUNW_SF_1 値は、次のように計算されます。
|
この計算は、再配置可能オブジェクト値と mapfile 値にそれぞれ適用されます。機能セクションが存在しない場合や、このセクションに CA_SUNW_SF_1 の値が含まれない場合、SF1_SUNW_FPKNW フラグも SF1_SUNW_FPUSED フラグも設定されていない場合は、オブジェクトのフレームポインタソフトウェア機能は不明になります。
SF1_SUNW_ADDR32 ソフトウェア機能フラグによって識別される 64 ビットオブジェクトは、32 ビットアドレス空間を必要とする最適化されたコードを含むことができます。この方法で識別される 64 ビットオブジェクトは、SF1_SUNW_ADDR32 フラグで識別されるかどうかにかかわらず、他の 64 ビットオブジェクトと相互運用できます。64 ビット入力再配置可能オブジェクト内で SF1_SUNW_ADDR32 フラグが現れると、リンカーによって作成される出力ファイル用に作成される CA_SUNW_SF_1 値に反映されます。
64 ビット実行可能ファイル内に SF1_SUNW_ADDR32 フラグが存在すると、関連付けられたプロセスは下位 32 ビットアドレス空間に確実に制限されます。この制限付きアドレス空間には、プロセススタックと、すべてのプロセス依存関係が含まれます。そのようなプロセスの内部では、すべてのオブジェクトは SF1_SUNW_ADDR32 フラグで識別されるかどうかにかかわらず、制限付き 32 ビットアドレス空間内に読み込まれます。
64 ビット共有オブジェクトは SF1_SUNW_ADDR32 フラグを含むことができます。ただし、制限付きアドレス空間要件は、SF1_SUNW_ADDR32 フラグを含む 64 ビット実行可能ファイルによってのみ設定できます。したがって、64 ビットの SF1_SUNW_ADDR32 共有オブジェクトは64 ビットの SF1_SUNW_ADDR32 実行可能ファイルに依存する必要があります。
制限付きでない 64 ビット実行可能ファイルを構築するとき、64 ビットの SF1_SUNW_ADDR32 共有オブジェクトがリンカーによって検出されると、警告が発生します。
$ cc -m64 -o main main.c -lfoo ld: warning: file libfoo.so: section .SUNW_cap: software capability ADDR32: \ requires executable be built with ADDR32 capability
制限付きでない 64 ビットの実行可能ファイルから作成されたプロセスによって 64 ビットの SF1_SUNW_ADDR32 共有オブジェクトが実行時に検出されると、致命的エラーが発生します。
$ ldd main libfoo.so => ./libfoo.so - software capability unsupported: 0x4 [ ADDR32 ] .... $ main ld.so.1: main: fatal: ./libfoo.so: software capability unsupported: 0x4 [ ADDR32 ]
実行可能ファイルには、mapfile を使用して SF1_SUNW_ADDR32 をシードできます。
$ cat mapfile $mapfile_version 2 CAPABILITY { SF += ADDR32; }; $ cc -m64 -o main main.c -Mmapfile -lfoo $ elfdump -H main Object Capabilities: index tag value [0] CA_SUNW_SF_1 0x4 [ SF1_SUNW_ADDR32 ]