リンカーとライブラリ

内部対応付け構造

ELF 基底のリンカーのもっとも重要なデータ構造の 1 つとして対応付け構造があります。上記で述べた初期値 mapfile に対応する初期対応付け構造は、コマンド実行時にリンカーで使われます。mapfile オプションが使われる場合、リンカーは mapfile を解析して、特定の値を初期対応付け構造に追加したり、上書きしたりします。

一般的な (ただし多少簡略化した) 対応付け構造が図 8-1に示してあります。「入口条件」ボックスは初期値の対応付け指示の情報に対応しており、「セグメント属性記述子」ボックスは、初期値のセグメント宣言の情報に対応しています。「出力記述子」ボックスは、各セグメントの下に来るセクションの詳細な属性を示します。セクション自体は丸で囲ってあります。

図 8-1 簡単な対応付け構造

Graphic

リンカーはセクションをセグメントに対応付ける際に、以下の手順で行います。

  1. セクションを読み取る際に、リンカーは合致するものを見つけるために、一連の入口条件を検査します。指定したすべての条件が合致する必要があります。

    図 8-1 では、text セグメントに入るセクションの場合、section_type$PROGBITSsection_flags?A!W でなければなりません。入口条件では名前は指定されていないので、名前 .text は必要ありません。入口条件では実行ビットは何も指定されていないので、セクションは (section_flags 値の) X!X のどちらかでもかまいません。

    入口条件に合致するものが見つからない場合、セクションはその他すべてのセグメントの後の a.out ファイルの最後に置かれます (この情報については、プログラムヘッダーエントリは作られません。詳細については、「プログラムヘッダー」を参照してください)。

  2. セクションがセグメントの中に入る際に、リンカーは以下のようにそのセグメントの既存の一連出力セクション記述子を検査します。

    セクションの属性値が既存の出力セクション記述子の属性値とまったく合致する場合、セクションは出力セクション記述子に対応するセクションの列挙の最後に置かれます。

    たとえば、section_name.data1section_type$PROGBITS、および section_flags?AWX のセクションは、図 8-1 の 2 番目の入口条件ボックスにあてはまり、data セグメントに置かれます。セクションは 2 番目の出力セクション記述子ボックスにちょうど一致し (.data1$PROGBITS?AWX)、このボックスに対応する連のセクションの最後に追加されます。fido.orover.o、および sam.o.data1 セクションはこのことを示しています。

    一致する出力セクション記述子が見つからず、同じ section_type の出力セクション記述子が他に存在する場合、セクションとして同じ属性値で新しい出力セクション記述子が作られ、そのセクションは新しい出力セクション記述子と対応づけられます。出力セクション記述子 (およびセクション) は、同じ section_type の最後の出力セクション記述子の後に置かれます。図 8-1.data2 セクションはこのやり方で置かれました。

    示された section_type の出力セクション記述子が他に存在しない場合、新しい出力セクション記述子が作られ、セクションはそのセクション内に置かれます。


    注 -

    入力セクションにユーザー定義の section_type が設定されている場合 (つまり、「セクション」で説明したように、SHT_LOUSERSHT_HIUSER の間)、これは $PROGBITS セクションとして扱われます。mapfile でこの section_type 値に名前を付ける方法はありませんが、これらのセクションは、入口条件でその他の属性値指定 (section_flagssection_name) を使って付け直せます。


  3. すべてのコマンド行で指定されたオブジェクトファイルとライブラリが読み取られた後、セグメントがセクションをまったく含まない場合、そのセグメントに対してはプログラムヘッダーエントリは作られません。


注 -

$SYMTAB$STRTAB$REL 型の入力セクションは、リンカーにより内部で使用されます。これらの section_type を参照する指示は、リンカーで作った出力セクションしかセグメントに対応付けできません。