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

印刷ビューの終了

更新: 2015 年 10 月
 
 

補助オブジェクト

デフォルトで、オブジェクトには、割り当て可能および割り当て不可の両方のセクションが含まれます。割り当て可能なセクションは、実行可能コードとそのコードが実行時に必要とするデータが含まれているセクションです。割り当て不可のセクションには、実行時にオブジェクトを実行するために必要でない補足的な情報が含まれています。これらのセクションは、デバッガおよびその他の可観測性ツールの動作をサポートします。オブジェクト内の割り当て不可のセクションは、実行時にオペレーティングシステムによってメモリーに読み込まれないため、どのようなサイズであっても、メモリーの使用やその他の実行時パフォーマンスの側面に影響を与えません。

利便性のため、割り当て可能なセクションと割り当て不可のセクションは、通常どちらも同じファイルに保持されます。しかし、これらのセクションを分離した方が有用な場合があります。

  • オブジェクトのサイズを減らして、広域ネットワーク経由でコピーする際の速度を向上させるため。

  • 高度に最適化されたコードの詳細なデバッグをサポートするには、大量のデバッグデータを必要とするため。最近のシステムでは、記述されるコードよりもデバッグデータの方が簡単に大きくなります。32 ビットオブジェクトのサイズは、4G バイトまでに制限されています。非常に大きな 32 ビットオブジェクトでは、デバッグデータのためにこの制限を超え、オブジェクトを作成できなくなる可能性があります。

  • 内部実装の詳細の露出を抑えるため。

従来は、これらの問題に対処するため、割り当て不可のセクションがオブジェクトから除去されていました。除去は有効ですが、あとで必要になる可能性があるデータも破棄されます。Solaris リンカーでは、代わりに割り当て不可のセクションを補助オブジェクトに書き込むことができます。この機能は、–z ancillary オプションを使用すると有効になります。

$ cc .... -z ancillary[=outfile] ....

補助ファイルには、デフォルトでプライマリ出力オブジェクトと同じ名前と .anc ファイル拡張子が付けられます。ただし、–z ancillary オプションに outfile の値を指定することで、別の名前を付けることができます。

–z ancillary が指定されると、リンカーは次の処理を実行します。

  • すべての割り当て可能なセクションがプライマリオブジェクトに書き込まれます。さらに、SHF_SUNW_PRIMARY セクションヘッダーフラグが設定された1 つ以上の入力セクションを含むすべての割り当て不可のセクションも、プライマリオブジェクトに書き込まれます。

  • 残りのすべての割り当て不可のセクションは、補助オブジェクトに書き込まれます。

  • 次の割り当て不可のセクションは、プライマリオブジェクトと補助オブジェクトの両方に書き込まれます。

    .shstrtab

    セクション名文字列テーブル。

    .symtab

    完全な非動的シンボルテーブル。

    .symtab_shndx

    .symtab に関連付けられたシンボルテーブルの拡張インデックスセクション。

    .strtab

    .symtab に関連付けられた非動的文字列テーブル。

    .SUNW_ancillary

    プライマリオブジェクトと補助オブジェクトの識別や検査しているオブジェクトの識別に必要な情報が格納されます。

  • プライマリオブジェクトとすべての補助オブジェクトには、同じセクションヘッダーの配列が含まれています。各セクションは、すべてのファイルで同じセクションインデックスを持っています。

  • プライマリオブジェクトと補助オブジェクトはいずれも同じセクションヘッダーを定義しますが、ほとんどのセクションのデータは前述のように 1 つのファイルに書き込まれます。セクションのデータが特定のファイルに存在しない場合は、SHF_SUNW_ABSENT セクションヘッダーフラグが設定され、sh_size フィールドが 0 になります。

この構成により、プライマリオブジェクトと補助オブジェクトのどちらからでも、セクションヘッダーの完全なリスト、完全なシンボルテーブル、およびプライマリオブジェクトと補助オブジェクトの完全なリストを取得できるようになっています。

次の例は、補助オブジェクトのベースとなる実装を示しています。補助オブジェクトは、ほかの点では標準的なコンパイルに –z ancillary コマンド行オプションを追加することで作成されます。file ユーティリティーは、結果として a.out という名前の実行可能ファイルと、a.out.anc という名前の関連する補助オブジェクトが生成されたことを示しています。

$ cat hello.c
#include    <stdio.h>

int
main(int argc, char **argv)
{
        (void) printf("hello, world\n");
        return (0);
}
$ cc -g -zancillary hello.c
$ file a.out a.out.anc
a.out: ELF 32-bit LSB executable 80386 Version 1 [FPU], dynamically \
    linked, not stripped, ancillary object a.out.anc
a.out.anc: ELF 32-bit LSB ancillary 80386 Version 1, primary object a.out
$ ./a.out
hello world

生成されたプライマリオブジェクトは、通常の方法で実行できる普通の実行可能ファイルです。補助オブジェクトを使用せずに作成し、その後 strip または mcs コマンドを使用して割り当て不可の内容を取り除いた実行可能ファイルと比べて、実行時の違いはありません。

前述のように、プライマリオブジェクトと補助オブジェクトには同じセクションヘッダーが含まれています。このしくみを理解するには、elfdump ユーティリティーを使用してこれらのセクションヘッダーを表示して比較すると有益です。次の表に、前のリンク編集の例からヘッダーを選択するためのセクションヘッダーの情報を示します。

インデックス
セクション名
タイプ
プライマリフラグ
補助フラグ
プライマリサイズ
補助サイズ
13
.text
PROGBITS
ALLOC EXECINSTR
ALLOC EXECINSTR SUNW_ABSENT
0x131
0
20
.data
PROGBITS
WRITE ALLOC
WRITE ALLOC SUNW_ABSENT
0x4c
0
21
.symtab
SYMTAB
0
0
0x450
0x450
22
.strtab
STRTAB
STRINGS
STRINGS
0x1ad
0x1ad
24
.debug_info
PROGBITS
SUNW_ABSENT
0
0
0x1a7
28
.shstrtab
STRTAB
STRINGS
STRINGS
0x118
0x118
29
.SUNW_ancillary
SUNW_ancillary
0
0
0x30
0x30

ほとんどのセクションのデータは、2 つのファイルのどちらかに存在し、もう一方のファイルには存在しません。SHF_SUNW_ABSENT セクションヘッダーフラグは、データが存在しないときに設定されます。実行時に必要な割り当て可能なセクションのデータは、プライマリオブジェクトに含まれています。デバッグに使用され、実行時には必要でない割り当て不可のセクションのデータは、補助ファイルに配置されます。割り当て不可のセクションの小さなセットが、両方のファイルにすべて存在します。これらは、プライマリオブジェクトと補助オブジェクトを関連付けるために使用される .SUNW_ancillary セクション、セクション名文字列テーブル .shstrtab、シンボルテーブル .symtab、およびその関連文字列テーブル .strtab です。

プライマリオブジェクトからシンボルテーブルを取り除くことができます。シンボルテーブルがないオブジェクトを検出したデバッガは、.SUNW_ancillary セクションを使用して補助オブジェクトを特定し、内部に含まれるシンボルにアクセスできます。

プライマリオブジェクトと関連するすべての補助オブジェクトには、すべてのオブジェクトを識別して関連付けることができる .SUNW_ancillary セクションが含まれています。

$ elfdump -T SUNW_ancillary a.out a.out.anc
a.out:
Ancillary Section:  .SUNW_ancillary
   index  tag                    value
     [0]  ANC_SUNW_CHECKSUM     0x8724
     [1]  ANC_SUNW_MEMBER       0x1         a.out
     [2]  ANC_SUNW_CHECKSUM     0x8724
     [3]  ANC_SUNW_MEMBER       0x1a3       a.out.anc
     [4]  ANC_SUNW_CHECKSUM     0xfbe2
     [5]  ANC_SUNW_NULL         0

a.out.anc:
Ancillary Section:  .SUNW_ancillary
   index  tag                    value
     [0]  ANC_SUNW_CHECKSUM     0xfbe2
     [1]  ANC_SUNW_MEMBER       0x1         a.out
     [2]  ANC_SUNW_CHECKSUM     0x8724
     [3]  ANC_SUNW_MEMBER       0x1a3       a.out.anc
     [4]  ANC_SUNW_CHECKSUM     0xfbe2
     [5]  ANC_SUNW_NULL         0          

両方のオブジェクトの補助セクションは、同じ数の要素を含み、最初の要素を除いて同一です。プライマリオブジェクトから先に、ファイル名を指定する MEMBER 要素と、それに続いてオブジェクトを識別する CHECKSUM によって、各オブジェクトが導入されます。この例では、プライマリオブジェクトは a.out であり、そのチェックサムは 0x8724 です。補助オブジェクトは a.out.anc であり、そのチェックサムは 0xfbe2 です。.SUNW_ancillary セクションの (プライマリオブジェクトの MEMBER 要素の前にある) 最初の要素は、常に検査しているファイルのチェックサムを含む CHECKSUM 要素です。

  • オブジェクトに .SUNW_ancillary セクションが存在することは、オブジェクトに関連する補助オブジェクトがあることを示しています。

  • プライマリオブジェクトと関連するすべての補助オブジェクトの名前は、いずれかのファイルの補助セクションから取得できます。

  • 最初のチェックサムの値を後続する各メンバーのチェックサムと比較することにより、大規模なファイルのセットからどのファイルを検査しているかを特定できます。


注 -  リンカーは、補助オブジェクトを入力として読み取りません。再配置可能オブジェクトが –z ancillary オプションを使用して作成され、作成されたオブジェクトがあとから、別のオブジェクトを構築するために参照される場合、補助オブジェクトからのセクションが最終オブジェクトに伝達されます。

デバッガによる補助オブジェクトのアクセスと使用

デバッガおよびその他の可観測性ツールは、オブジェクトの完全なビューを作成するために、プライマリオブジェクトファイルと補助オブジェクトファイルで見つかった情報をマージする必要があります。これは、1 つのファイルの情報を処理するのとまったく同じです。このマージは、同じセクションヘッダーを含むプライマリオブジェクトと補助オブジェクト、および単一のシンボルテーブルによって簡略化されます。

デバッガでこれらのファイルに含まれる情報をまとめるには、次の手順を使用します。

  1. プライマリオブジェクトまたはいずれかの補助オブジェクトから先に、.SUNW_ancillary セクションを見つけます。このセクションが存在することで、そのオブジェクトが補助グループの一部として特定されます。このセクションには、ファイルの完全なリストを取得し、それらのどれが現在検査しているファイルかを特定するために使用できる情報が含まれています。

  2. 検査しているオブジェクトのセクションヘッダー配列を最初のテンプレートとして使用して、メモリー内にセクションヘッダー配列を作成します。

  3. .SUNW_ancillary セクションで識別された各ファイルを順に開き、読み取ります。ファイルごとに、SHF_SUNW_ABSENT フラグが設定されていない各セクションの情報をメモリー内のセクションヘッダー配列に埋め込みます。

この結果、すべてのセクションのデータへのポインタを含むセクションヘッダーの完全なメモリー内コピーができます。この情報を取得したあと、デバッガは単一ファイルの場合と同じように処理を続行し、実行中のプログラムにアクセスしてそれを制御できます。


注 -  補助オブジェクトの ELF 定義では、1 つのプライマリオブジェクトと任意の数の補助オブジェクトが提供されます。現時点では、Oracle Solaris リンカーはすべての割り当て不可のセクションを含む単一の補助オブジェクトのみを生成します。これは将来変更される可能性があります。デバッガおよびその他の可観測性ツールは、補助オブジェクトが複数存在する一般的なケースに対応できるように作成されるべきです。