リンカーとライブラリ

対応付けの例

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


例 8-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 あるいは割当て可能な実行プログラムである必要はありません (「か」の関係は、2 行目の $PROGBITS「か」?AX で示されるように、同じ行の属性の間に存在します。「または」の関係は、2 行目の $PROGBITS ?AX 「または」3 行目の .data のように、複数の行にまたがる同じセグメントの属性の間に存在します)。

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

5 行目では、donkey セグメントを暗黙の内に宣言しています。入口条件は、このすべての .data セクションをこのセグメントに振り向けるようになっています。実際には、3 行目の monkey の入口条件はこれらのセクションのすべてを取り込むので、このセグメントに入るセクションはありません。6 行目では、segment_flags 値は ?RX に設定され、整列値は 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 セグメントが、この例では扱われています。1 行目では、text セグメントの virtual_address が 0xf0004000 になるように、またこのセグメントのアドレス計算の一部分として ELF ヘッダーやプログラムヘッダーを含めないように宣言しています。2 行目と 3 行目では、セグメント内セクションの順序付けを有効にし、このセグメントでは .text セクションと .rodata セクションが最初の 2 つのセクションになるように指定しています。この結果、.text セクションは仮想アドレスが 0xf0004000 になり、その直後に .rodata セクションがきます。

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