リンカーとライブラリ

対応付けの例

次にユーザー定義の mapfile の例を示します。左の数字は、説明のためにつけたものです。実際には、数字の右の情報だけが、mapfile に含まれます。


例 9–1 ユーザー定義の mapfile

    1.  elephant : .data : peanuts.o *popcorn.o; 
    2.  monkey : $PROGBITS ?AX; 
    3.  monkey : .data; 
    4.  monkey = LOAD V0x80000000 L0x4000; 
    5.  donkey : .data; 
    6.  donkey = ?RX A0x1000; 
    7.  text = V0x80008000;

4 つの別々のセグメントがこの例では扱われています。暗黙の内に宣言されたセグメント elephant (1 行目) は、ファイル peanuts.o および popcorn.o からすべての .data セクションを受け取ります。*popcorn.o は、リンカーに与えられるすべての popcorn.o ファイルと一致します。ファイルは、現在のディレクトリにある必要はありません。他方、/var/tmp/peanuts.o がリンカーに提供された場合、これには * が前に付かないため peanuts.o とは一致しません。

暗黙の内に宣言されたセグメント monkey (2 行目) は $PROGBITS および割当て可能な実行プログラム (?AX) の両方になっているすべてのセクション、さらに .data (3 行目) という名前のすべてのセクション (セグメント elephant に入らなかったもの) を受け取ります。別の行で section_namesection_typesection_flags の値が指定されているので、monkey セグメントに入る .data セクションが、$PROGBITS あるいは割当て可能な実行プログラムである必要はありません。

同じ行の属性の間には「and」関係があります。たとえば、2 行目の $PROGBITS?AX は「and」関係です。同じセグメントの属性が複数行にある場合は、それらの間に「or」関係があります。たとえば、2 行目の $PROGBITS ?AX と 3行目の .data は「or」関係です。

monkey セグメントは、segment_typeLOADsegment_flagsRWXvirtual_addressphysical_address は無指定、長さ整列の値は、デフォルトとして 2 行目で暗黙の内に宣言されています。4 行目では、monkeysegment_type 値は LOAD に設定されています。segment_type 属性は変わらないため、警告は出ません。virtual_address 値は 0x80000000 に、最大 length 値は 0x4000 に設定されています。

5 行目では、donkey セグメントを暗黙の内に宣言しています。エントランス基準 は、このすべての .data セクションをこのセグメントに振り向けるようになっています。実際には、3 行目の monkey のエントランス基準はこれらのセクションのすべてを取り込むので、このセグメントに入るセクションはありません。6 行目では、segment_flags 値は ?RX に、alignment 値は 0x1000 に設定されています。これらの属性値の両方が変化するため、警告が出ます。

7 行目では、テキストセグメントの virtual_address 値を 0x80008000 に設定します。

ユーザー定義の mapfile の例は、説明のために警告を出すように設計されています。次の例では指令の順序を変更して警告を避けています。

    1.  elephant : .data : peanuts.o *popcorn.o; 
    4.  monkey = LOAD V0x80000000 L0x4000; 
    2.  monkey : $PROGBITS ?AX; 
    3.  monkey : .data; 
    6.  donkey = ?RX A0x1000; 
    5.  donkey : .data; 
    7.  text = V0x80008000;

次の mapfile の例では、セグメント内セクションの順序付けを使っています。

    1.  text = LOAD ?RXN V0xf0004000; 
    2.  text | .text; 
    3.  text | .rodata; 
    4.  text : $PROGBITS ?A!W; 
    5.  data = LOAD ?RWX R0x1000;

text セグメントおよび data セグメントが、この例では扱われています。text セグメントの virtual_address 0xf0004000 になるように、またこのセグメントのアドレス計算の一部分として ELF ヘッダーやプログラムヘッダーを含めないように宣言しています。2 行目と 3 行目では、セグメント内セクションの順序付けを有効にし、このセグメントでは .text セクションと .rodata セクションが最初の 2 つのセクションになるように指定しています。この結果、.text セクションは仮想アドレスが 0xf0004000 になり、その直後に .rodata セクションがきます。

text セグメントを構成するその他の $PROGBITS セクションは、.rodata セクションのあとにきます。5 行目では data セグメントを指定し、その仮想アドレスは 0x1000 バイト境界で始まらなければならないと指定しています。data を構成する最初のセクションも、ファイルイメージ内の 0x1000 バイト境界に存在します。