共有オブジェクトのレイアウト
これは、ILINKが生成した共有オブジェクトの順番に並んだレイアウトです。
ELFヘッダ | ELFヘッダファイル |
プログラムヘッダ | 目次のようなもの |
|
|
| 共有オブジェクトのインターフェースを含む |
| 動的な名前を含む |
| グローバルオフセットテーブル(GOT)の再配置 |
| GOTのPLT (プロシージャリンケージテーブル)の部分の再配置 |
| 外部コード参照用のプロシージャリンケージテーブル(PLT) |
| 通常のread-only出力セクション |
| 動的リンカ用の様々なデータを含む |
| グローバルオフセットテーブル(GOT) |
| 通常の初期化データ出力セクション |
| 通常のゼロ初期化データ出力セクション |
| 通常の初期化されていない出力セクション |
ELFヘッダ
通常の標準に準拠したELFファイルヘッダ。これは常にファイル内の最初のバイトで構成され、セクションではありません。このヘッダは動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。
プログラムヘッダ
プログラムヘッダはすべての実行可能ELFファイルと共有ELFファイルの一部であり、セクションではありません。このヘッダは、動的リンカが必要とするため、ターゲットプロセッサにダウンロードされます。
通常3つのプログラムヘッダがあります。
読み取り専用コンテンツ(コードと定数)用のヘッダ1つ
読み取り/書き込みコンテンツ(初期化データおよびゼロ初期化データ)用のヘッダ1つ
.dynamicセクション用ヘッダ1つ
.dynamicセクションは読み取り/書き込みセグメントの一部です。異なるエントリになるので、動的リンカはすぐに見つけれます。
ほかのセグメントタイプもありますが、IARの実装では、load (ROM/RAM)とdynamicの2つのみをサポートしています。
.hash
共有オブジェクトのELFセクション。動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。.dynsym セクションのシンボルのより効率的な検索に使用されます。.hash は、標準の ELF ハッシュセクションであり、標準に準拠したすべての動的リンカで動作します。
.dynsym
共有オブジェクトのELFセクション。動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。共有オブジェクトのインターフェース、必要になる(外部)シンボル、およびエクスポートするシンボル(グローバル)を追跡するために使用します。.dynsym は、標準の ELF シンボルテーブルセクションです。
.dynstr
共有オブジェクトのELFセクション。動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。共有オブジェクト内のすべての動的な名前が含まれます(ELF 内の名前は文字列テーブルへのインデックスです)。.dynstr は、標準の ELF 文字列テーブルセクションです。
.rel.dyn
共有オブジェクトのELFセクション。動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。これには、動的リンカが GOT エントリの eager ロードを実行するのに必要な再配置ディレクティブが含まれます。.rel.dyn は、標準の ELF 再配置セクションです。
「共有オブジェクトのロードとアンロード」を参照してください。
.rel.plt
共有オブジェクトのELFセクション。動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。これには、動的リンカが GOT 内のPLT エントリの lazy ロードを実行するのに必要な再配置ディレクティブが含まれます。.rel.plt は、標準の ELF 再配置セクションです。
「共有オブジェクトのロードとアンロード」を参照してください。
.plt
共有オブジェクトのELFセクション。外部コードが共有オブジェクトによってアクセスされるとき、コードはこのセクションに制御を移行するので、ターゲットプロセッサにダウンロードされます。すべての外部コードシンボルには、独自のPLTエントリがあります。PLTエントリは、GOTから外部シンボルのアドレスを取得し、そのアドレスに制御を移行します。.text セクションのコール / ジャンプは、対応する PLT エントリにリダイレクトされます。.plt は、標準の ELF SHT_PROGBITS セクションです。
.text
共有オブジェクトのELFセクション。このセクションには通常、共有オブジェクトのコードおよび定数があり、ターゲットプロセッサにダウンロードされます。.text は、標準の ELF SHT_PROGBITS セクションです。
.data.rel.ro
An ELF section in the shared object.
Constant pointers to data—in either RAM or ROM—must be relocated. To make relocation possible, the compiler generates the constant pointers in this writable ELF section (but only when --shared has been specified—modules with pointers that are not shared can always be relocated at link time because the final address is known).
Because the pointers themselves are const they cannot be modified at runtime, but must be relocated at load time. In many cases, but not always, you can avoid load-time relocation by using relative references or the global offset table (GOT).
In a shared linking operation, the linker will preserve the relocations of .data.rel.ro sections and make sure that they are resolved when the shared object is loaded. The relocations will be generated in the .rel.dyn section (to ensure that they are always resolved—they cannot be lazy, see 共有オブジェクトのロードとアンロード).
注記
Because the .data.rel.ro section is writable, any constants it holds can be modified at runtime. For that reason, you should if possible write-protect it using the MMU (if such a mechanism is available).
.data.rel.ro is a standard ELF SHT_PROGBITS section.
.dynamic
共有オブジェクトのELFセクション。動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。これには、動的リンカが共有オブジェクトにアクセスするために必要な情報(GOT がどこに配置されているか、どのような種類の再配置が使用されているか)が含まれています。.dynamic は、標準の ELF 動的セクションです。
ILINKによって生成された共有オブジェクトは、標準のELF DTタグと一部のGCC拡張を使用します。
.got
共有オブジェクトのELFセクション。動的リンカに必要になるのでターゲットプロセッサにダウンロードされます。データまたは外部コードがアクセスされるたびにアクセスされます。GOTは基本的にアドレスの配列に格納されます。動的リンカは GOT にアドレスを書き込み、すべてのアクセスはそれらのアドレスを使用します。.got は、標準の ELF SHT_PROGBITS セクションです。
.data
共有オブジェクトのELFセクション。このセクションには通常、共有オブジェクトの初期化データがあり、ターゲットプロセッサにダウンロードされます。(動的リンカはコンテンツの初期化を行います。).data は、標準のELF SHT_PROGBITS セクションです。
.bss
共有オブジェクトのELFセクション。このセクションには、共有オブジェクトのゼロ初期化データがあり、ターゲットプロセッサにダウンロードされます。(動的リンカはコンテンツのゼロ初期化を行います。).bss は、標準のELF SHT_NOBITS セクションです。
.uninit
共有オブジェクトのELFセクション。このセクションには、共有オブジェクトの初期化していないデータが含まれます。それはセグメントの一部ではありません。そのアドレスはプログラムヘッダでカバーされていません(「プログラムヘッダ」参照)。動的リンカは .uninit セクションのバイトにはアクセスしません。これは、この初期化されていないセクションに未定義のバイトが含まれていることを意味し、潜在的に危険です。これを安全に管理するのはアプリケーションの責任です。.uninit は、標準のELF SHT_NOBITS セクションで、非標準な方法で扱われます。書き込み可能なコンテンツは通常初期化またはゼロ初期化されます。
コンテンツリストのサンプル
これは、ielfdumparm使用して作成した、共有オブジェクトのコンテンツのリスト(ダンプ)のサンプルです。
32-bit little-endian shared object ELF file for Advanced RISC Machines ARM File version 1, header size 52, section header string section #28. Flags 0x500'0000 (ARM ELF revision 5 [AAELF 2.0]) Entry 0x0 3 program headers, each 32 bytes, at offset 0x34 29 section headers, each 40 bytes, at offset 0x10ec
SEGMENTS: Type Offset Virtual Physical File Sz Mem Sz Flags Align ‑‑‑‑ ‑‑‑‑‑‑ ‑‑‑‑‑‑- ‑‑‑‑‑‑‑‑ ‑‑‑‑‑‑- ‑‑‑‑‑‑ ‑‑‑‑- ‑‑‑‑- 0: load 0x0 0x0 0x0 0x1c4 0x1c4 0x5 X R 0x1000 1: load 0x1c4 0x11c4 0x11c4 0x88 0x90 0x6 WR 0x1000 2: dynamic 0x1c4 0x11c4 0x11c4 0x68 0x68 0x6 WR 0x4
SECTIONS:
Name Type Addr Offset Size Aln Lnk Inf ESz Flags
‑‑‑‑ ‑‑‑‑ ‑‑‑‑ ‑‑‑‑‑‑ ‑‑‑‑ ‑‑- ‑‑- ‑‑- ‑‑- ‑‑‑‑-
1: .hash hash 0x94 0x94 0x2c 0x4 2 4 0x2 A
2: .dynsym dynsym 0xc0 0xc0 0x70 0x4 3 3 16 0x2 A
3: .dynstr strtab 0x130 0x130 0x13 0x4 0x2 A
4: .rel.dyn rel 0x144 0x144 0x18 0x4 2 9 8 0x2 A
5: .rel.plt rel 0x15c 0x15c 0x8 0x4 2 9 8 0x2 A
6: .plt pbits 0x164 0x164 0x20 0x4 4 0x6 AX
7: .text pbits 0x184 0x184 0x3e 0x4 1 0x6 AX
8: .dynamic dyn 0x11c4 0x1c4 0x68 0x4 3 8 0x3 WA
9: .got pbits 0x122c 0x22c 0x1c 0x4 4 0x3 WA
10: .data pbits 0x1248 0x248 0x4 0x4 1 0x3 WA
11: .bss nobits 0x124c 0x24c 0x8 0x4 1 0x3 WA
12: .noinit nobits 0x1254 0x24c 0x8 0x4 1 0x3 WA
13: .debug_abbrev pbits 0x24c 0x81 1
14: .debug_aranges pbits 0x2d0 0x40 1
15: .debug_frame pbits 0x310 0x55 1
16: .debug_info pbits 0x368 0x4b6 1
17: .debug_line pbits 0x820 0xd9 1
18: .debug_loc pbits 0x8fc 0x34 1
19: .debug_macinfo pbits 0x930 0x5 1
20: .debug_pubnames pbits 0x938 0x7e 1
21: .iar.debug_frame pbits 0x9b8 0x24 1
22: .iar.debug_line pbits 0x9dc 0xb8 1
23: .comment pbits 0xa94 0x184 1
24: .iar.rtmodel pbits 0xc18 0x25 1
25: .ARM.attributes arm_attr 0xc40 0x2c 1
26: .symtab symtab 0xc6c 0x240 0x4 27 20 16
27: .strtab strtab 0xeac 0x11a 0x4
28: .shstrtab strtab 0xfc8 0x122 0x4注記
次のことに気を付けてください。
ROMセグメント(
Wフラグなし)、RAMセグメント(Wフラグ)、動的セグメントの3つのセグメントがあります。動的なセグメント(.dynamicセクション)は、RAMセグメント内にありますが、問題ではありません。.dynamicは、最初の書き込み可能なセクション(Wフラグがついている最初のセクション)であるため、loadセグメントのアライメント(このファイルではso_alignmentが0x1000となる)がオフセットに追加される最初のセクションです。so_alignment ディレクティブを参照してください。すべてのROMセクションのアドレスはOffsetの値と同じで、すべての
pbitsタイプのRAMセクションのアドレスはOffset +so_alignmentになります。(nobitsタイプのRAMセクションにはファイル内にバイトがないため、それらのアドレスはOffset +so_alignmentに等しいとは限りません。)
Aフラグ (Alloc)のついていないセクションは、ターゲットにダウンロードされません。それらのセクションは、実行には必要のない補助的な情報(デバッグ情報など)が含まれます。