ELF ベースのリンカーのもっとも重要なデータ構造の 1 つとして対応付け構造があります。初期値 mapfile に対応する初期対応付け構造が、リンカーにより使用されます。ユーザーの mapfile はすべて、初期対応付け構造内に特定の値を追加または上書きします。
一般的な (ただし多少簡略化した) 対応付け構造を図 8–1 に示します。「エントランス基準」ボックスは、初期値の対応付け指示内の情報に対応しています。「セグメント属性記述子」ボックスは、初期値のセグメント宣言内の情報に対応しています。「出力記述子」ボックスは、各セグメントの下に来るセクションの詳細な属性を示します。セクション自体は丸で囲んであります。
リンカーはセクションをセグメントに対応付ける際に、以下の手順で行います。
セクションを読み取る際に、リンカーは合致するものを見つけるために、一連のエントランス基準を検査します。指定したすべての条件が合致する必要があります。
図 8–1 では、text セグメントに入るセクションの場合、section_type は $PROGBITS、section_flags は ?A!W でなければなりません。エントランス基準では名前は指定されていないので、名前 .text は必要ありません。エントランス基準では実行ビットは何も指定されていないので、セクションは section_flags 値の X と !X のどちらかでもかまいません。
エントランス基準に合致するものが見つからない場合、セクションはその他すべてのセグメントの後の出力ファイルの最後に置かれます。この情報に関するプログラムヘッダーエントリは作成されません。
セクションがセグメントの中に入る際に、リンカーは以下のようにそのセグメントの既存の一連の出力セクション記述子を検査します。
セクションの属性値が既存の出力セクション記述子の属性値とまったく合致する場合、セクションは出力セクション記述子に対応するセクションの列挙の最後に置かれます。
たとえば、section_name が .data1、section_type が $PROGBITS、および section_flags が ?AWX のセクションは、図 8–1 の 2 番目のエントランス基準ボックスにあてはまり、data セグメントに置かれます。セクションは 2 番目の出力セクション記述子ボックスにちょうど一致し (.data1、$PROGBITS、?AWX)、このボックスに対応する一連のセクションの最後に追加されます。fido.o、rover.o、および sam.o の .data1 セクションは、このことを示しています。
一致する出力セクション記述子が見つからず、同じ section_type の出力セクション記述子が他に存在する場合、セクションとして同じ属性値で新しい出力セクション記述子が作られ、そのセクションは新しい出力セクション記述子と対応づけられます。出力セクション記述子およびセクションは、同じセクションタイプの最後の出力セクション記述子の後に置かれます。図 8–1 の .data2 セクションはこの方法で配置されました。
指定されたセクションタイプの出力セクション記述子が他に存在しない場合、新しい出力セクション記述子が作られ、セクションはそのセクション内に置かれます。
入力セクションが、SHT_LOUSER と SHT_HIUSER の間にユーザー定義のセクションタイプ値を保持する場合、このセクションタイプ値は $PROGBITS セクションとして処理されます。mapfile でこの section_type 値に名前を付ける方法はありませんが、これらのセクションは、エントランス基準でその他の属性値指定 (section_flags、section_name) を使って付け直すことができます。
すべてのコマンド行で指定されたオブジェクトファイルとライブラリが読み取られた後、セグメントがセクションをまったく含まない場合、そのセグメントに対してはプログラムヘッダーエントリは作られません。
$SYMTAB、$STRTAB、$REL、および $RELA 型の入力セクションは、リンカーにより内部で使用されます。これらのセクションタイプを参照する指示は、リンカーで作った出力セクションしかセグメントに対応付けできません。