ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
リンカーとライブラリ Oracle Solaris 11 Information Library (日本語) |
LOAD_SEGMENT/NOTE_SEGMENT/NULL_SEGMENT 指令
SIZE_SYMBOL 属性 (LOAD_SEGMENT のみ)
SYMBOL_SCOPE/SYMBOL_VERSION 指令
定義済みセグメントとエントランス基準のための mapfile 指令
パート IV ELF アプリケーションバイナリインタフェース
ユーザー定義の mapfile の例を次に示します。左の数字は、説明のためにつけたものです。実際には、数字の右の情報だけが、mapfile に含まれます。
この例では、セグメントを定義し、セグメントに入力セクションを割り当てる方法について説明します。
例 10-1 セクションからセグメントへの基本的な割り当て
1 $mapfile_version 2 2 LOAD_SEGMENT elephant { 3 ASSIGN_SECTION { 4 IS_NAME=.data; 5 FILE_PATH=peanuts.o; 6 }; 7 ASSIGN_SECTION { 8 IS_NAME=.data; 9 FILE_OBJNAME=popcorn.o; 10 }; 11 }; 12 13 LOAD_SEGMENT monkey { 14 VADDR=0x80000000; 15 MAX_SIZE=0x4000; 16 ASSIGN_SECTION { 17 TYPE=progbits; 18 FLAGS=ALLOC EXECUTE; 19 }; 20 ASSIGN_SECTION { 21 IS_NAME=.data 22 }; 23 }; 24 25 LOAD_SEGMENT donkey { 26 FLAGS=READ EXECUTE; 27 ALIGN=0x1000; 28 ASSIGN_SECTION { 29 IS_NAME=.data; 30 }; 31 }; 32 33 LOAD_SEGMENT text { 34 VADDR=0x80008000 35 };
4 つの別々のセグメントがこの例では扱われています。1 行目に示すように、すべての mapfile は $mapfile_version 宣言で始まります。elephant セグメント (2 行目から 11 行目) は、peanuts.o または popcorn.o ファイルからすべてのデータセクションを受け取ります。オブジェクト popcorn.o はアーカイブから取得でき、その場合、アーカイブファイルは任意の名前を持つことができます。あるいは、popcorn.o はベース名が popcorn.o の任意のファイルから取得できます。これに対して、 peanuts.o は同一の名前のファイルからのみ取得できます。たとえば、/var/tmp/peanuts.o がリンク編集時に指定された場合、peanuts.o と一致しません。
monkey セグメント (13 行目から 23 行目) には、仮想アドレス 0x80000000 および最大長 0x4000 が指定されています。このセグメントは、PROGBITS および割り当て可能な実行可能プログラムの両方であるすべてのセクション、さらに elephant セグメントに含まれていない .data という名前のすべてのセクションを受け取ります。monkey セグメントに入る .data セクションは、PROGBITS でも割り当て可能な実行可能プログラムである必要もありません。これは、.data セクションは 16 行目でなく 20 行目のエントランス基準に一致するためです。このことは、ASSIGN_SECTION 属性内のサブ属性間には and 関係が存在し、単一セグメントの異なる ASSIGN_SECTION 属性間には or 関係が存在することを示しています。
donkey セグメント (25 行目から 31 行目) は、デフォルト以外のアクセス権フラグと配置を指定し、.data という名前のすべてのセクションを受け入れます。ただし、このセグメントにはどのセクションも割り当てられず、その結果、donkey セグメントは出力オブジェクトに含まれません。この理由は、リンカーは mapfile に現れる順序でエントランス基準を検証するためです。この mapfile では、elephant セグメントが一部の .data セクションを受け入れ、monkey セグメントが残りを受け取るため、donkey には何も残りません。
33 行目から 35 行目では、text セグメントの仮想アドレスを 0x80008000 に設定します。text セグメントは、「定義済みセグメント」で説明されているように、標準の定義済みセグメントの 1 つであるため、このステートメントは新しいセグメントを作成するのではなく、既存のセグメントを変更します。
次の mapfile の例では、定義済みの text セグメントと data セグメント、ヘッダーオプション、およびセグメント内のセクションの順序付けを操作します。
例 10-2 定義済みセクションの操作とセクションからセグメントへの割り当て
1 $mapfile_version 2 2 HDR_NOALLOC; 3 4 LOAD_SEGMENT text { 5 VADDR=0xf0004000; 6 FLAGS=READ EXECUTE; 7 OS_ORDER=.text .rodata; 9 ASSIGN_SECTION { 10 TYPE=PROGBITS; 11 FLAGS=ALLOC !WRITE; 12 }; 13 }; 14 15 LOAD_SEGMENT data { 16 FLAGS=READ WRITE EXECUTE; 17 ALIGN=0x1000; 18 ROUND=0x1000; 19 };
先頭行は常に、使用する mapfile 言語のバージョンを宣言します。HDR_NOALLOC 指令 (2 行目) では、結果オブジェクトは、オブジェクトの最初に割り当て可能なセグメント (定義済み text セグメント) の内部に ELF ヘッダーまたはプログラムヘッダー配列を含んではならないということが指定されています。
4 行目から 13 行目のセグメント指令は、text セグメントに仮想アドレスとアクセス権フラグを設定します。この指令では、.text という名前のセクションがセグメントの先頭に配置され、.rodata という名前のすべてのセクションがその後に続き、その他のすべてのセクションはこれらの後に続く必要があることが指定されます。最後に、割り当てることができる書き込み不可の PROGBITS セクションがセグメントに割り当てられます。
15 行目から 19 行目のセグメント指令は、data セグメントを 0x1000 境界に配置する必要があることを指定します。これは、セグメント内の先頭セクションを同じ配置方法で整列する効果があります。セグメントの長さは、配置方法と同じ値の倍数値に切り上げられます。セグメントのアクセス権は、読み取り、書き込み、および実行に設定されます。