JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
リンカーとライブラリ     Oracle Solaris 10 8/11 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

1.  Oracle Solaris リンカーの紹介

2.  リンカー

3.  実行時リンカー

4.  共有オブジェクト

5.  アプリケーションバイナリインタフェースとバージョン管理

6.  サポートインタフェース

7.  オブジェクトファイル形式

ファイル形式

データ表現

ELF ヘッダー

ELF 識別

データの符号化

セクション

セクションのマージ

特殊セクション

「COMDAT」セクション

グループセクション

機能セクション

ハッシュテーブルセクション

移動セクション

注釈セクション

再配置セクション

再配置型 (プロセッサ固有)

SPARC: 再配置型

64 ビット SPARC: 再配置型

32 ビット x86: 再配置型

x64: 再配置型

文字列テーブルセクション

シンボルテーブルセクション

シンボル値

シンボルテーブルのレイアウトと規則

シンボルソートセクション

レジスタシンボル

Syminfo テーブルセクション

バージョン管理セクション

バージョン定義セクション

バージョン依存セクション

バージョンシンボルセクション

動的リンク

プログラムヘッダー

ベースアドレス

セグメントへのアクセス権

セグメントの内容

プログラムの読み込み (プロセッサ固有)

プログラムインタプリタ

実行時リンカー

動的セクション

大域オフセットテーブル (プロセッサ固有)

プロシージャーのリンクテーブル (プロセッサ固有)

32 ビット SPARC: プロシージャーのリンクテーブル

64 ビット SPARC: プロシージャーのリンクテーブル

32 ビット x86: プロシージャーのリンクテーブル

x64: プロシージャーのリンクテーブル

8.  スレッド固有領域 (TLS)

9.  mapfile

A.  リンカーのクイックリファレンス

B.  バージョン管理の手引き

C.  動的ストリングトークンによる依存関係の確立

D.  直接結合

E.  System V Release 4 (バージョン 1) Mapfile

F.  リンカーとライブラリのアップデートおよび新機能

索引

ファイル形式

オブジェクトファイルはプログラムのリンクと実行の両方に関係します。利便性と効率性のため、オブジェクトファイルの形式には、リンクと実行の異なる要求に合わせて、2 つの平行した見方があります。次の図にオブジェクトファイルの編成を示します。

図 7-1 オブジェクトファイル形式

image:オブジェクトファイル形式です。

ELF ヘッダーはオブジェクトファイルの先頭に存在し、ファイル編成を記述する「ロードマップ」を保持します。


注 - ELF ヘッダーの位置のみがファイル内で固定されています。ELF 形式には柔軟性があるため、ヘッダーテーブル、セクション、およびセグメントの順序は特に決まっていません。この図に示したのは、Oracle Solaris OS で使用される典型的なレイアウトです。


「セクション」は、 ELF ファイル内で処理可能な最小単位 (これ以上分割できない単位) です。「セグメント」は、セクションの集合です。セグメントは、exec(2) または実行時リンカーでメモリーイメージに対応付けできる最小単位です。

セクションは、リンクの観点から見たオブジェクトファイルの情報の大部分を保持します。このデータには、命令、データ、シンボルテーブル、再配置情報などが含まれます。セクションに関しては、この章の前半で説明します。セグメントとプログラムの実行の観点から見たファイルの構造に関しては、この章の後半で説明します。

プログラムヘッダーテーブル (存在する場合) は、システムにプロセスイメージの作成方法を通知します。プロセスイメージの生成に使用されるファイル (実行可能ファイルと共有オブジェクト) には、プログラムヘッダーテーブルが存在する必要があります。再配置可能オブジェクトでは、プログラムヘッダーテーブルは必要ありません。

セクションヘッダーテーブルには、ファイルのセクションを記述する情報が入っています。セクションヘッダーテーブルには各セクションのエントリが存在します。各エントリは、セクション名、セクションサイズなどの情報が含まれます。リンク編集で使用されるファイルには、セクションヘッダーテーブルが存在しなければなりません。

データ表現

オブジェクトファイルの形式は、8 ビットバイト、32 ビットアーキテクチャー、および 64 ビットアーキテクチャーを持つさまざまなプロセッサをサポートしています。しかしながら、データ表現は、より大きな、またはより小さなアーキテクチャーに拡張できるように意図されています。表 7-1表 7-2 に、32 ビットデータタイプと 64 ビットデータタイプの一覧を示します。

オブジェクトファイルは、いくつかの制御データをマシンに依存しない形式で表現します。この形式は、オブジェクトファイルの共通の識別および解釈を規定します。オブジェクトファイルの残りのデータは、このオブジェクトファイルが作成されたマシンとは関係なく、対象となるプロセッサ用に符号化されています。

表 7-1 ELF 32 ビットデータタイプ

名前
サイズ
整列
目的
Elf32_Addr
4
4
符号なしプログラムアドレス
Elf32_Half
2
2
符号なし、中程度の整数
Elf32_Off
4
4
符号なしファイルオフセット
Elf32_Sword
4
4
符号付き整数
Elf32_Word
4
4
符号なし整数
unsigned char
1
1
符号なし、短い整数

表 7-2 ELF 64 ビットデータタイプ

名前
サイズ
整列
目的
Elf64_Addr
8
8
符号なしプログラムアドレス
Elf64_Half
2
2
符号なし、中程度の整数
Elf64_Off
8
8
符号なしファイルオフセット
Elf64_Sword
4
4
符号付き整数
Elf64_Word
4
4
符号なし整数
Elf64_Xword
8
8
符号なし、長い整数
Elf64_Sxword
8
8
符号付き、長い整数
unsigned char
1
1
符号なし、短い整数

オブジェクトファイルの形式で定義されるすべてのデータ構造は、該当クラスの自然なサイズと整列ガイドラインに従います。データ構造に明示的にパッドを入れることで、4 バイトオブジェクトに対して 4 バイト整列を保証したり構造サイズを 4 の倍数に設定したりできます。また、データはファイルの先頭から適切に整列されます。したがってたとえば、Elf32_Addr メンバーが存在する構造はファイル内において 4 バイト境界で整列されます。同様に、Elf64_Addr メンバーが存在する構造は 8 バイト境界で整列されます。


注 - 移植性を考慮して、ELF ではビットフィールドを使用していません。


ELF ヘッダー

ELF ヘッダーには実際のサイズが記録されるため、オブジェクトファイル内の制御構造は大きくなることがあります。オブジェクトファイルの形式が変更されると、プログラムは、予想より大きい、または小さい制御構造に遭遇する可能性があります。大きくなった場合は、追加された部分を無視することができるかもしれません。不足する情報の取り扱いは状況に依存し、拡張が定義されたときに定められます。

ELF ヘッダーの構造体は次のとおりです。sys/elf.h を参照してください。

#define EI_NIDENT       16
 
typedef struct {
        unsigned char   e_ident[EI_NIDENT]; 
        Elf32_Half      e_type;
        Elf32_Half      e_machine;
        Elf32_Word      e_version;
        Elf32_Addr      e_entry;
        Elf32_Off       e_phoff;
        Elf32_Off       e_shoff;
        Elf32_Word      e_flags;
        Elf32_Half      e_ehsize;
        Elf32_Half      e_phentsize;
        Elf32_Half      e_phnum;
        Elf32_Half      e_shentsize;
        Elf32_Half      e_shnum;
        Elf32_Half      e_shstrndx;
} Elf32_Ehdr;

typedef struct {
        unsigned char   e_ident[EI_NIDENT]; 
        Elf64_Half      e_type;
        Elf64_Half      e_machine;
        Elf64_Word      e_version;
        Elf64_Addr      e_entry;
        Elf64_Off       e_phoff;
        Elf64_Off       e_shoff;
        Elf64_Word      e_flags;
        Elf64_Half      e_ehsize;
        Elf64_Half      e_phentsize;
        Elf64_Half      e_phnum;
        Elf64_Half      e_shentsize;
        Elf64_Half      e_shnum;
        Elf64_Half      e_shstrndx;
} Elf64_Ehdr;
e_ident

先頭のバイト列は、オブジェクトファイルであることを示す印です。これらのバイトには、機種に依存しない、ファイルの内容を復号化または解釈するためのデータが入ります。詳細な説明は、「ELF 識別」に記載されています。

e_type

オブジェクトファイルの種類を示します。次の種類が存在します。

名前
意味
ET_NONE
0
ファイルタイプが存在しない
ET_REL
1
再配置可能ファイル
ET_EXEC
2
実行可能ファイル
ET_DYN
3
共有オブジェクトファイル
ET_CORE
4
コアファイル
ET_LOPROC
0xff00
プロセッサに固有
ET_HIPROC
0xffff
プロセッサに固有

コアファイルの内容は指定されていませんが、ET_CORE タイプはコアファイルを示すために予約されます。ET_LOPROC から ET_HIPROC までの値 (それぞれを含む) は、プロセッサ固有のセマンティクスのために予約されています。ほかの値は、将来の使用に備えて保留されます。

e_machine

個々のファイルに必要なアーキテクチャーを指定します。関連するアーキテクチャーを、次の表に示します。

名前
意味
EM_NONE
0
マシンが存在しない
EM_SPARC
2
SPARC
EM_386
3
Intel 80386
EM_SPARC32PLUS
18
Sun SPARC 32+
EM_SPARCV9
43
SPARC V9
EM_AMD64
62
AMD 64

ほかの値は、将来の使用に備えて保留されます。プロセッサ固有の ELF 名の識別には、機種名が使用されます。たとえば、e_flags に定義されるフラグでは、接頭辞 EF_ が使用されます。EM_XYZ マシンの WIDGET というフラグは、EF_XYZ_WIDGET と呼ばれます。

e_version

オブジェクトファイルのバージョンを示します。次のバージョンが存在します。

名前
意味
EV_NONE
0
無効バージョン
EV_CURRENT
>=1
現在のバージョン

値 1 は最初のファイル形式を示し、EV_CURRENT の値は、現在のバージョン番号を示すために必要に応じて変化します。

e_entry

システムが制御を最初に渡す仮想アドレスを保持し、仮想アドレスが与えられると、プロセスが起動します。ファイルに関連するエントリポイントが存在しない場合、このメンバーは 0 を保持します。

e_phoff

プログラムヘッダーテーブルのファイルオフセットを保持します (単位: バイト)。ファイルにプログラムヘッダーテーブルが存在しない場合、このメンバーは 0 を保持します。

e_shoff

セクションヘッダーテーブルのファイルオフセットを保持します (単位: バイト)。ファイルにセクションヘッダーテーブルが存在しない場合、このメンバーは 0 を保持します。

e_flags

ファイルに対応付けられたプロセッサ固有のフラグを保持します。フラグ名は、EF_machine「_flag」という形式をとります。このメンバーは、現在 x86 に対しては 0 です。SPARC の場合のフラグを、次の表に示します。

名前
意味
EF_SPARC_EXT_MASK
0xffff00
ベンダー拡張マスク
EF_SPARC_32PLUS
0x000100
V8+ 共通機能
EF_SPARC_SUN_US1
0x000200
Sun UltraSPARC 1 拡張
EF_SPARC_HAL_R1
0x000400
HAL R1 拡張
EF_SPARC_SUN_US3
0x000800
Sun UltraSPARC 3 拡張
EF_SPARCV9_MM
0x3
メモリーモデルのマスク
EF_SPARCV9_TSO
0x0
トータルストアオーダリング (TSO)
EF_SPARCV9_PSO
0x1
パーシャルストアオーダリング (PSO)
EF_SPARCV9_RMO
0x2
リラックスメモリーオーダリング (RMO)
e_ehsize

ELF ヘッダーのサイズ (単位: バイト)。

e_phentsize

ファイルのプログラムヘッダーテーブルの 1 つのエントリのサイズ (単位:バイト)。すべてのエントリは同じサイズです。

e_phnum

プログラムヘッダーテーブルのエントリ数。e_phentsizee_phnum を掛けると、テーブルのサイズ (単位: バイト) が求められます。ファイルにプログラムヘッダーテーブルが存在しない場合、e_phnum は値 0 を保持します。

プログラムヘッダーの数が PN_XNUM (0xffff) 以上である場合、このメンバーは値 PN_XNUM (0xffff) を保持します。プログラムヘッダーテーブルエントリの実際の数は、インデックス 0 のセクションヘッダーの sh_info フィールドに含まれます。そうでない場合、初期セクションヘッダーエントリの sh_info メンバーには値 0 が入っています。表 7-6 および表 7-7 を参照してください。

e_shentsize

セクションヘッダーのサイズ (単位:バイト)。1 つのセクションヘッダーは、セクションヘッダーテーブルの 1 つのエントリです。すべてのエントリは同じサイズです。

e_shnum

セクションヘッダーテーブルのエントリ数。e_shentsizee_shnum を掛けると、セクションヘッダーテーブルのサイズ (単位: バイト) が求められます。ファイルにセクションヘッダーテーブルが存在しない場合、e_shnum は値 0 を保持します。

セクション数が SHN_LORESERVE (0xff00) 以上の場合、e_shnum の値は 0 になります。セクションヘッダーテーブルエントリの実際の数は、インデックス 0sh_size フィールドに含まれます。そうでない場合、初期セクションヘッダーエントリの sh_size メンバーには値 0 が入っています。表 7-6 および表 7-7 を参照してください。

e_shstrndx

セクション名文字列テーブルに対応するエントリのセクション ヘッダーテーブルインデックス。ファイルにセクション名文字列テーブルが存在しない場合、このメンバーは値 SHN_UNDEF を保持します。

セクション名文字列テーブルセクションのインデックスが SHN_LORESERVE (0xff00) 以上の場合、このメンバーの値は SHN_XINDEX (0xffff) となり、セクション名文字列テーブルセクションの実際のインデックスはインデックス 0 のセクションヘッダーの sh_link フィールドに入っています。そうでない場合、初期セクションヘッダーエントリの sh_link メンバーには値 0 が入っています。表 7-6 および表 7-7 を参照してください。

ELF 識別

ELF はオブジェクトファイルの枠組みを提供し、複数のプロセッサ、複数のデータ符号化、複数のクラスのマシンをサポートします。このオブジェクトファイルファミリをサポートするため、ファイルの初期バイトによりファイルの解釈方法が指定されます。これらの初期バイトは、問い合わせが行われるプロセッサにも、ファイルのほかの内容にも依存しません。

ELF ヘッダーおよびオブジェクトファイル の初期バイトは、e_ident メンバーに一致します。

表 7-3 ELF 識別インデックス

名前
目的
EI_MAG0
0
ファイルの識別
EI_MAG1
1
ファイルの識別
EI_MAG2
2
ファイルの識別
EI_MAG3
3
ファイルの識別
EI_CLASS
4
ファイルのクラス
EI_DATA
5
データの符号化
EI_VERSION
6
ファイルのバージョン
EI_OSABI
7
オペレーティングシステム / ABI の識別
EI_ABIVERSION
8
ABI のバージョン
EI_PAD
9
パッドバイトの開始
EI_NIDENT
16
e_ident[] のサイズ

次のインデックスは、次の値を保持するバイトにアクセスします。

EI_MAG0 - EI_MAG3

ファイルを ELF オブジェクトファイルとして識別する 4 バイトの「マジックナンバー」。次の表を参照してください。

名前
位置
ELFMAG0
0x7f
e_ident[EI_MAG0]
ELFMAG1
'E'
e_ident[EI_MAG1]
ELFMAG2
'L'
e_ident[EI_MAG2]
ELFMAG3
'F'
e_ident[EI_MAG3]
EI_CLASS

バイト e_ident[EI_CLASS] は、ファイルのクラスまたは容量を示します。次の表にファイルのクラスを示します。

名前
意味
ELFCLASSNONE
0
無効なクラス
ELFCLASS32
1
32 ビットオブジェクト
ELFCLASS64
2
64 ビットオブジェクト

ファイル形式は、最大マシンのサイズを最小マシンに押しつけることなしにさまざまなサイズのマシン間で互換性が維持されるように設計されています。ファイルのクラスは、オブジェクトファイルコンテナのデータ構造によって使用される基本タイプを定義します。オブジェクトファイルセクションに含まれるデータは、異なるプログラミングモデルに準拠する場合があります。

クラス ELFCLASS32 は、4 ギガバイトまでのファイルと仮想アドレス空間が存在するマシンをサポートします。このクラスは、表 7-1 で定義される基本タイプを使用します。

クラス ELFCLASS64 は、64 ビット SPARC や x64 などの 64 ビットアーキテクチャー用に予約されています。このクラスは、表 7-2 で定義される基本タイプを使用します。

EI_DATA

バイト e_ident[EI_DATA] は、オブジェクトファイルのプロセッサ固有のデータの符号化を指定します (次の表を参照)。

名前
意味
ELFDATANONE
0
無効な符号化
ELFDATA2LSB
1
図 7-2 を参照してください。
ELFDATA2MSB
2
図 7-3 を参照してください。

これらの符号化の詳細は、「データの符号化」で説明します。ほかの値は、将来の使用に備えて保留されます。

EI_VERSION

バイト e_ident[EI_VERSION] は、ELF ヘッダーバージョン番号を指定します。現在この値は、EV_CURRENT でなければなりません。

EI_OSABI

バイト e_ident[EI_OSABI] は、オブジェクトのターゲット先となる ABI とともにオペレーティングシステムを識別します。ほかの ELF 構造体内のフィールドの中には、オペレーティングシステム特有または ABI 特有の意味を持つフラグおよび値を保持するものがあります。これらのフィールドの解釈は、このバイトの値によって決定されます。

EI_ABIVERSION

バイト e_ident[EI_ABIVERSION] は、オブジェクトのターゲット先となる ABI のバージョンを識別します。このフィールドは、ABI の互換性のないバージョンを識別するために使用します。このバージョン番号の解釈は、EI_OSABI フィールドで識別される ABI によって異なります。プロセッサについて EI_OSABI フィールドに値が何も指定されていない場合、または EI_OSABI バイトの特定の値によって決定される ABI についてバージョンの値が何も指定されていない場合は、指定なしを示すものとして値 0 が使用されます。

EI_PAD

この値は、e_ident の使用されていないバイトの先頭を示します。これらのバイトは保留され、0 に設定されます。オブジェクトファイルを読み取るプログラムは、これらの値を無視します。

データの符号化

ファイルのデータ符号化方式は、ファイルの整数タイプを解釈する方法を指定します。クラス ELFCLASS32 のファイルおよびクラス ELFCLASS64 のファイルは、1、2、4、および 8 バイトを占める整数を使用して、オフセット、アドレス、およびその他の情報を表現します。定義されている符号化方式の下では、オブジェクトは次の図の説明のように表されます。バイト番号は、左上隅に示されています。

ELFDATA2LSB を符号化すると、最下位バイトが最低位アドレスを占める 2 の補数値が指定されます。この符号化は、一般的にはよく「リトルエンディアン」と呼ばれます。

図 7-2 データの符号化方法 ELFDATA2LSB

image:ELFDATA2LSB データの符号化方法。

ELFDATA2MSB を符号化すると、最上位バイトが最低位アドレスを占める 2 の補数値が指定されます。この符号化は、一般的にはよく「ビッグエンディアン」と呼ばれます。

図 7-3 データの符号化方法 ELFDATA2MSB

image:ELFDATA2MSB データの符号化方法。

セクション

オブジェクトファイルのセクションヘッダーテーブルを使用すると、ファイルのセクションすべてを見つけ出すことができます。セクションヘッダーテーブルは、Elf32_Shdr 構造体または Elf64_Shdr 構造体の配列です。セクションヘッダーテーブルインデックスは、この配列への添字です。ELF ヘッダーの e_shoff メンバーは、ファイルの先頭からセクションヘッダーテーブルまでのバイトオフセットを示します。e_shnum メンバーは、セクションヘッダーテーブルに含まれるエントリ数を示します。e_shentsize メンバーは、各エントリのバイト単位の大きさを示します。

セクション数が SHN_LORESERVE (0xff00) 以上の場合、e_shnum の値は SHN_UNDEF (0) になります。セクションヘッダーテーブルエントリの実際の数は、インデックス 0sh_size フィールドに含まれます。そうでない場合、初期エントリの sh_size メンバーには値 0 が入っています。

セクションヘッダーテーブルインデックスの中には、インデックスサイズが制限されている文脈で予約されているものがあります。たとえば、シンボルテーブルエントリの st_shndx メンバー、 ELF ヘッダーの e_shnum メンバーと e_shstrndx メンバーなどがそうです。このような文脈では、予約値はオブジェクトファイル内の実際のセクションを示しません。また、このような文脈では、エスケープ値は、実際のセクションインデックスがどこかもっと大きなフィールド内に存在することを示します。

表 7-4 ELF セクションの特殊インデックス

名前
SHN_UNDEF
0
SHN_LORESERVE
0xff00
SHN_LOPROC
0xff00
SHN_BEFORE
0xff00
SHN_AFTER
0xff01
SHN_AMD64_LCOMMON
0xff02
SHN_HIPROC
0xff1f
SHN_LOOS
0xff20
SHN_LOSUNW
0xff3f
SHN_SUNW_IGNORE
0xff3f
SHN_HISUNW
0xff3f
SHN_HIOS
0xff3f
SHN_ABS
0xfff1
SHN_COMMON
0xfff2
SHN_XINDEX
0xffff
SHN_HIRESERVE
0xffff

注 - インデックス 0 は未定義値として予約されますが、セクションヘッダーテーブルにはインデックス 0 のエントリが存在します。つまり、ELF ヘッダーの e_shnum メンバーが、ファイルのセクションヘッダーテーブルに 6 つのエントリが存在することを示している場合、これら 6 つのエントリにはインデックス 0 から 5 までが与えられます。先頭のエントリの内容は、この項の末尾に記述します。


SHN_UNDEF

未定義、存在しない、無関係など、無意味なセクション参照。たとえば、セクション番号 SHN_UNDEF に関して「定義された」シンボルは、未定義シンボルです。

SHN_LORESERVE

予約済みインデックスの範囲の下限。

SHN_LOPROC - SHN_HIPROC

この両端を含む範囲の値は、プロセッサ固有のセマンティクスのために予約されています。

SHN_LOOS - SHN_HIOS

この両端を含む範囲の値は、オペレーティングシステム固有のセマンティクスのために予約されています。

SHN_LOSUNW - SHN_HISUNW

この両端を含む範囲の値は、Sun 固有のセマンティクスのために予約されています。

SHN_SUNW_IGNORE

このセクションインデックスは、再配置可能オブジェクト内の一時的なシンボル定義を提供します。dtrace(1M) の内部使用のため予約されています。

SHN_BEFORE, SHN_AFTER

SHF_LINK_ORDER および SHF_ORDERED セクションフラグとともに先頭および末尾のセクションの順序付けを行います。表 7-8 を参照してください。

SHN_AMD64_LCOMMON

x64 固有の共通ブロックラベル。このラベルは SHN_COMMON に似ていますが、大規模な共通ブロックの識別をサポートする点が異なります。

SHN_ABS

対応する参照の絶対値。たとえば、セクション番号 SHN_ABS からの相対で定義されたシンボルは絶対値をとり、再配置の影響を受けません。

SHN_COMMON

このセクションに対して相対的に定義されるシンボルは、FORTRAN の COMMON や割り当てられていない C 外部変数などの共通シンボルです。これらのシンボルは、一時的シンボルと呼ばれることもあります。

SHN_XINDEX

実際のセクションヘッダーインデックスが大きすぎて格納先のフィールドに入りきらないことを示すエスケープ値。ヘッダーセクションインデックスは、このインデックスが出現する構造体に固有の別の場所に存在します。

SHN_HIRESERVE

予約済みインデックスの範囲の上限。システムは、SHN_LORESERVE から SHN_HIRESERVE までのインデックスを予約します。値は、セクションヘッダーテーブルを参照しません。セクションヘッダーテーブルには予約されているインデックスのエントリは存在しません。

セクションには、ELF ヘッダー、プログラムヘッダーテーブル、セクションヘッダーテーブルを除く、オブジェクトファイルのすべての情報が存在します。また、オブジェクトファイルのセクションは次の条件を満たします。

セクションヘッダーの構造体は、次のとおりです。sys/elf.h を参照してください。

typedef struct {
        elf32_Word      sh_name;
        Elf32_Word      sh_type;
        Elf32_Word      sh_flags;
        Elf32_Addr      sh_addr;
        Elf32_Off       sh_offset;
        Elf32_Word      sh_size;
        Elf32_Word      sh_link;
        Elf32_Word      sh_info;
        Elf32_Word      sh_addralign;
        Elf32_Word      sh_entsize;
} Elf32_Shdr;

typedef struct {
        Elf64_Word      sh_name;
        Elf64_Word      sh_type;
        Elf64_Xword     sh_flags;
        Elf64_Addr      sh_addr;
        Elf64_Off       sh_offset;
        Elf64_Xword     sh_size;
        Elf64_Word      sh_link;
        Elf64_Word      sh_info;
        Elf64_Xword     sh_addralign;
        Elf64_Xword     sh_entsize;
} Elf64_Shdr;
sh_name

セクション名。このメンバー値はセクションヘッダーの文字列テーブルセクションへのインデックスで、ヌル文字で終わる文字列の位置を示します。セクション名とその説明は、表 7-10 を参照してください。

sh_type

セクションの内容とセマンティクスを分類します。セクションの種類とその説明は、表 7-5 を参照してください。

sh_flags

セクションは、さまざまな属性を記述する 1 ビットフラグをサポートします。フラグの定義は、表 7-8 を参照してください。

sh_addr

セクションがプロセスのメモリーイメージに現れる場合、このメンバーはセクションの先頭バイトが存在しなければならないアドレスを与えます。セクションがプロセスのメモリーイメージに現れない場合、このメンバーには 0 が存在します。

sh_offset

ファイルの先頭からセクションの先頭バイトまでのバイトオフセット。SHT_NOBITS 型のセクションの場合はファイル内のスペースを占めないため、このメンバーは、ファイル内の概念的なオフセットを示します。

sh_size

セクションのサイズ (バイト)。セクションのタイプが SHT_NOBITS でないかぎり、セクションはファイルの sh_size バイトを占めます。タイプが SHT_NOBITS のセクションは、0 以外のサイズをとることがありますが、ファイルのスペースは占めません。

sh_link

セクションヘッダーテーブルのインデックスリンク。このリンクの解釈は、セクションのタイプに依存します。値については、表 7-9 を参照してください。

sh_info

追加情報。情報の解釈は、セクションのタイプに依存します。値については、表 7-9 を参照してください。このセクションヘッダーの sh_flags フィールドに属性 SHF_INFO_LINK が含まれている場合、このメンバーはセクションヘッダーテーブルインデックスを表します。

sh_addralign

いくつかのセクションには、アドレス整列制約が存在します。たとえば、あるセクションが 2 語で構成されるデータを保持している場合、システムはそのセクション全体に対して 2 語単位の整列を保証しなければなりません。この場合、sh_addr の値は、sh_addralign の値を法として 0 でなければなりません。現在、0、および 2 の非負整数累乗のみが許可されています。値 01 は、セクションに整列制約が存在しないことを意味します。

sh_entsize

いくつかのセクションは、サイズが一定のエントリのテーブル (シンボルテーブルなど) を保持します。このようなセクションに対してこのメンバーは、各エントリのサイズ (単位: バイト) を与えます。サイズが一定のエントリのテーブルをセクションが保持しない場合、このメンバーには 0 が格納されます。

セクションヘッダーの sh_type メンバーは、次の表に示すようにこのセクションのセマンティクスを示します。

表 7-5 ELF セクションタイプ、sh_type

名前
SHT_NULL
0
SHT_PROGBITS
1
SHT_SYMTAB
2
SHT_STRTAB
3
SHT_RELA
4
SHT_HASH
5
SHT_DYNAMIC
6
SHT_NOTE
7
SHT_NOBITS
8
SHT_REL
9
SHT_SHLIB
10
SHT_DYNSYM
11
SHT_INIT_ARRAY
14
SHT_FINI_ARRAY
15
SHT_PREINIT_ARRAY
16
SHT_GROUP
17
SHT_SYMTAB_SHNDX
18
SHT_LOOS
0x60000000
SHT_LOSUNW
0x6fffffef
SHT_SUNW_capchain
0x6fffffef
SHT_SUNW_capinfo
0x6ffffff0
SHT_SUNW_symsort
0x6ffffff1
SHT_SUNW_tlssort
0x6ffffff2
SHT_SUNW_LDYNSYM
0x6ffffff3
SHT_SUNW_dof
0x6ffffff4
SHT_SUNW_cap
0x6ffffff5
SHT_SUNW_SIGNATURE
0x6ffffff6
SHT_SUNW_ANNOTATE
0x6ffffff7
SHT_SUNW_DEBUGSTR
0x6ffffff8
SHT_SUNW_DEBUG
0x6ffffff9
SHT_SUNW_move
0x6ffffffa
SHT_SUNW_COMDAT
0x6ffffffb
SHT_SUNW_syminfo
0x6ffffffc
SHT_SUNW_verdef
0x6ffffffd
SHT_SUNW_verneed
0x6ffffffe
SHT_SUNW_versym
0x6fffffff
SHT_HISUNW
0x6fffffff
SHT_HIOS
0x6fffffff
SHT_LOPROC
0x70000000
SHT_SPARC_GOTDATA
0x70000000
SHT_AMD64_UNWIND
0x70000001
SHT_HIPROC
0x7fffffff
SHT_LOUSER
0x80000000
SHT_HIUSER
0xffffffff
SHT_NULL

セクションヘッダーが無効であることを示します。このセクションヘッダーには、関連付けられているセクションは存在しません。セクションヘッダーのほかのメンバーの値は不定です。

SHT_PROGBITS

プログラムによって定義された情報を示します。その形式や意味はすべて、プログラムによって決定されます。

SHT_SYMTABSHT_DYNSYMSHT_SUNW_LDYNSYM

シンボルテーブルを示します。一般に、SHT_SYMTAB セクションはリンク編集に関するシンボルを示します。このテーブルには完全なシンボルテーブルとして、動的リンクに不要な多くのシンボルが存在することがあります。また、オブジェクトファイルには SHT_DYNSYM セクション (動的リンクシンボルの最小セットを保持して領域を節約している) が存在することがあります。

SHT_DYNSYM は、SHT_SUNW_LDYNSYM セクションで拡張することもできます。この追加セクションは、局所関数シンボルを実行時環境に提供しますが、動的リンクには必要ありません。このセクションを追加することで、SHT_SYMTAB を割り当てることができないために、テーブルが使用できないまたはファイルから削除されたときでも、デバッガは実行時状況で正確なスタックトレースを行うことができます。また、このセクションは、dladdr(3C) が使用する追加シンボリック情報を実行時環境に提供します。

SHT_SUNW_LDYNSYM セクションと SHT_DYNSYM セクションの両方があるときは、リンカーはそれらのデータ領域を並べて配置します。SHT_SUNW_LDYNSYM セクションは SHT_DYNSYM セクションの前に配置されます。このように配置されることで、SHT_SYMTAB の追加シンボルを含めて、これらの 2 つのテーブルを大きな 1 つの連続したシンボルテーブルとして表示することができます。

詳細は、「シンボルテーブルセクション」を参照してください。

SHT_STRTABSHT_DYNSTR

文字列テーブルを示します。オブジェクトファイルには、複数の文字列テーブルセクションを指定できます。詳細は、「文字列テーブルセクション」を参照してください。

SHT_RELA

32 ビットクラスのオブジェクトファイル用のタイプ Elf32_Rela など、明示的加数を含む再配置エントリを示します。オブジェクトファイルには、複数の再配置セクションを指定できます。詳細は、「再配置セクション」を参照し てください。

SHT_HASH

シンボルハッシュテーブルを示します。動的にリンクされたオブジェクトファイルには、シンボルハッシュテーブルが存在しなければなりません。現在、オブジェクトファイルにはハッシュテーブルは 1 つしか存在できませんが、この制約は将来、緩和されるかもしれません。詳細は、「ハッシュテーブルセクション」を参照してください。

SHT_DYNAMIC

動的リンク処理用の情報を示します。現在、オブジェクトファイルには動的セクションを 1 つだけ含めることができます。詳細は、「動的セクション」を参照してください。

SHT_NOTE

ファイルに何らかの方法で付加すべき情報を示します。詳細は、「注釈セクション」を参照してください。

SHT_NOBITS

ファイル内の領域を占有しないセクションを示します。このセクションは、その他の点では SHT_PROGBITS に似ています。このセクションにはデータは存在しませんが、sh_offset メンバーには概念上のファイルオフセットが存在します。

SHT_REL

32 ビットクラスのオブジェクトファイル用のタイプ Elf32_Rel など、明示的加数を含まない再配置エントリを示します。オブジェクトファイルには、複数の再配置セクションを指定できます。詳細は、「再配置セクション」を参照し てください。

SHT_SHLIB

セマンティクスが定義されていない予約済みセクションを示します。この型のセクションが存在するプログラムは、ABI に準拠しません。

SHT_INIT_ARRAY

初期設定関数へのポインタの配列を含むセクションを示します。配列内の各ポインタは、void を戻り値とする、パラメータを持たないプロシージャーと見なされます。詳細は、「初期設定および終了セクション」を参照してください。

SHT_FINI_ARRAY

終了関数へのポインタの配列を含むセクションを示します。配列内の各ポインタは、void を戻り値とする、パラメータを持たないプロシージャーと見なされます。詳細は、「初期設定および終了セクション」を参照してください。

SHT_PREINIT_ARRAY

ほかのすべての初期設定関数の前に呼び出される関数へのポインタの配列を含むセクションを示します。配列内の各ポインタは、void を戻り値とする、パラメータを持たないプロシージャーと見なされます。詳細は、「初期設定および終了セクション」を参照してください。

SHT_GROUP

セクショングループを示します。セクショングループとは、関連する一連のセクションであり、リンカーは 1 つの単位として扱う必要があります。タイプが SHT_GROUP であるセクションは、再配置可能オブジェクト内にしか存在できません。詳細は、「グループセクション」を参照してください。

SHT_SYMTAB_SHNDX

拡張されたセクションインデックスが入ったセクション (シンボルテーブルに関連 付けられている) を示します。シンボルテーブルによって参照されているセクションヘッダーインデックスのいずれかにエスケープ値 SHN_XINDEX が含まれる場合は、関連する SHT_SYMTAB_SHNDX が必要です。

SHT_SYMTAB_SHNDX セクションは、Elf32_Word 値の配列です。この配列には、関連するシンボルテーブルエントリごとに 1 つのエントリが存在します。これらの値は、シンボルテーブルエントリが定義されているセクションヘッダーインデックスを示します。一致する Elf32_Word に実際のセクションヘッダーインデックスが含まれるのは、対応するシンボルテーブルエントリの st_shndx フィールドにエスケープ値 SHN_XINDEX が含まれる場合だけです。そうでない場合、エントリは必ず SHN_UNDEF (0) です。

SHT_LOOSSHT_HIOS

この両端を含む範囲の値は、オペレーティングシステム固有のセマンティクスのために予約されています。

SHT_LOSUNWSHT_HISUNW

この両端を含む範囲の値は、Oracle Solaris OS 用のセマンティクスのために予約されています。

SHT_SUNW_capchain

機能ファミリメンバーを集めたインデックスの配列です。配列の最初の要素は連鎖バージョンメンバーです。この要素の後に来るのは、0 で終了する一連の機能シンボルインデックスです。インデックスの 0 で終了する各グループは機能ファミリを表します。各ファミリの最初の要素は機能の先頭のシンボルです。次の要素はファミリメンバーを指します。詳細については、「機能セクション」を参照してください。

SHT_SUNW_capinfo

シンボルテーブルエントリを機能要件に関連付けるインデックスの配列と、その先頭の機能シンボルです。シンボル機能を定義するオブジェクトには SHT_SUNW_cap セクションが含まれています。SHT_SUNW_cap セクションのヘッダー情報は、関連する SHT_SUNW_capinfo セクションを指します。SHT_SUNW_capinfo セクションのヘッダー情報は、関連するシンボルテーブルセクションを指します。詳細については、「機能セクション」を参照してください。

SHT_SUNW_symsort

並んで配置される SHT_SUNW_LDYNSYM セクションと SHT_DYNSYM セクションによって作成される動的なシンボルテーブルへのインデックスの配列。これらのインデックスは、SHT_SUNW_LDYNSYM セクションの開始位置からの相対値です。インデックスはメモリーアドレスを含み、上記のシンボルを参照します。インデックスは、アドレスの昇順にシンボルを参照するようにソートされます。

SHT_SUNW_tlssort

並んで配置される SHT_SUNW_LDYNSYM セクションと SHT_DYNSYM セクションによって作成される動的なシンボルテーブルへのインデックスの配列。これらのインデックスは、SHT_SUNW_LDYNSYM セクションの開始位置からの相対値です。インデックスは、スレッド固有領域シンボルを参照します。第 8 章スレッド固有領域 (TLS)を参照してください。インデックスは、オフセットの昇順にシンボルを参照するようにソートされます。

SHT_SUNW_LDYNSYM

非大域シンボル用の動的シンボルテーブル。すでに説明した「SHT_SYMTAB SHT_DYNSYMSHT_SUNW_LDYNSYM」を参照してください。

SHT_SUNW_dof

dtrace(1M) の内部使用のため予約されています。

SHT_SUNW_cap

機能要件を指定します。詳細については、「機能セクション」を参照してください。

SHT_SUNW_SIGNATURE

モジュール検証用の署名を示します。

SHT_SUNW_ANNOTATE

注釈セクションの処理は、デフォルトのセクション処理規則のすべてに従います。唯一の例外は、注釈セクションが割り当て不可能なメモリー内に存在する場合に発生します。セクションのヘッダーフラグ SHF_ALLOC が設定されていないと、 リンカーは、このセクションに対する未対応の再配置をすべて黙って無視します。

SHT_SUNW_DEBUGSTRSHT_SUNW_DEBUG

デバッグ情報を示します。このタイプのセクションは、リンカーの -s オプションを使用するか、あるいはリンク編集後に strip(1) を使用して、オブジェクトから取り除くことができます。

SHT_SUNW_move

部分的に初期設定されたシンボルを処理するためのデータを示します。詳細は、「移動セクション」を参照してください。

SHT_SUNW_COMDAT

同一データの複数のコピーを単一のコピーに低減することを可能にするセクションを示します。詳細は、「「COMDAT」セクション」を参照してください。

SHT_SUNW_syminfo

追加のシンボル情報を示します。詳細は、「Syminfo テーブルセクション」を参照してください。

SHT_SUNW_verdef

このファイルで定義された細粒度のバージョンを示します。詳細は、「バージョン定義セクション」を参照してください。

SHT_SUNW_verneed

このファイルが必要とする細粒度の依存関係を示します。詳細は、「バージョン依存セクション」を参照してください。

SHT_SUNW_versym

シンボルと、ファイルが提供するバージョン定義との関係を記述したテーブルを示します。詳細は、「バージョンシンボルセクション」を参照してください。

SHT_LOPROC - SHT_HIPROC

この両端を含む範囲の値は、プロセッサ固有のセマンティクスのために予約されています。

SHT_SPARC_GOTDATA

GOT からの相対アドレスを使って参照される、SPARC 固有のデータを示します。つまり、シンボル _GLOBAL_OFFSET_TABLE_ に割り当てられたアドレスに対する相対的なオフセットです。64 ビット SPARC の場合、このセクション内のデータは、リンク編集時に GOT アドレスの {+-} 2^32 バイト内の場所に結合されなければなりません。

SHT_AMD64_UNWIND

スタックを巻き戻すための巻き戻し (unwind) 関数テーブルエントリを含む、x64 固有のデータを示します。

SHT_LOUSER

アプリケーションプログラム用として予約されているインデックスの範囲の下限を指定します。

SHT_HIUSER

アプリケーションプログラム用として予約されているインデックスの範囲の上限を指定します。SHT_LOUSER から SHT_HIUSER までのセクション型は、現在の、または将来のシステム定義セクション型と競合することなくアプリケーションで使用できます。

ほかのセクション型の値は、保留されています。先に述べたとおり、そのインデックスが未定義セクション参照を示している場合でも、インデックス 0 (SHN_UNDEF) のセクションヘッダーは存在します。その値は次の表のとおりです。

表 7-6 ELF セクションヘッダーテーブルエントリ: インデックス 0

名前
注意
sh_name
0
名前が存在しない
sh_type
SHT_NULL
使用されない
sh_flags
0
フラグが存在しない
sh_addr
0
アドレスが存在しない
sh_offset
0
ファイルオフセットが存在しない
sh_size
0
サイズが存在しない
sh_link
SHN_UNDEF
リンク情報が存在しない
sh_info
0
補助情報が存在しない
sh_addralign
0
整列が存在しない
sh_entsize
0
エントリが存在しない

セクションまたはプログラムヘッダーの数が ELF ヘッダーデータサイズを超えた場合、セクションヘッダー 0 の構成要素を使って拡張 ELF ヘッダー属性が定義されます。その値は次の表のとおりです。

表 7-7 ELF 拡張セクションヘッダーテーブルエントリ: インデックス 0

名前
注意
sh_name
0
名前が存在しない
sh_type
SHT_NULL
使用されない
sh_flags
0
フラグが存在しない
sh_addr
0
アドレスが存在しない
sh_offset
0
ファイルオフセットが存在しない
sh_size
e_shnum
セクションヘッダーテーブルのエントリ数
sh_link
e_shstrndx
セクション名文字列テーブルに対応するエントリのセクション ヘッダーインデックス
sh_info
e_phnum
プログラムヘッダーテーブルのエントリ数
sh_addralign
0
整列が存在しない
sh_entsize
0
エントリが存在しない

セクションヘッダーの sh_flags メンバーは、セクションの属性を記述する 1 ビットフラグを保持します。

表 7-8 ELF セクションの属性フラグ

名前
SHF_WRITE
0x1
SHF_ALLOC
0x2
SHF_EXECINSTR
0x4
SHF_MERGE
0x10
SHF_STRINGS
0x20
SHF_INFO_LINK
0x40
SHF_LINK_ORDER
0x80
SHF_OS_NONCONFORMING
0x100
SHF_GROUP
0x200
SHF_TLS
0x400
SHF_MASKOS
0x0ff00000
SHF_AMD64_LARGE
0x10000000
SHF_ORDERED
0x40000000
SHF_EXCLUDE
0x80000000
SHF_MASKPROC
0xf0000000

sh_flags にフラグビットが設定されると、属性がセクションに対して「オン」になります。設定されない場合は、属性が「オフ」になるか、または適用されません。定義されていない属性は保留され、0 に設定されています。

SHF_WRITE

プロセス実行中に書き込み可能にすべきセクションを示します。

SHF_ALLOC

プロセス実行中にメモリーを占有するセクションを示します。いくつかの制御セクションは、オブジェクトファイルのメモリーイメージに存在しません。この属性は、これらのセクションに対してオフです。

SHF_EXECINSTR

実行可能なマシン命令を含むセクションを示します。

SHF_MERGE

マージして重複をなくすことの可能なデータを含むセクションを示します。同時に SHF_STRINGS フラグが設定されていないかぎり、このセクション内のデータ要素は統一されたサイズになります。各要素のサイズは、セクションヘッダーの sh_entsize フィールドで指定されます。同時に SHF_STRINGS フラグも設定されている場合は、データ要素はヌル文字で終わる文字列で構成されています。各文字のサイズは、セクションヘッダーの sh_entsize フィールドで指定されます。

SHF_STRINGS

ヌル文字で終わっている文字列で構成されるセクションを示します。各文字のサイズは、セクションヘッダーの sh_entsize フィールドで指定されます。

SHF_INFO_LINK

このセクションヘッダーの sh_info フィールドには、セクションヘッダーテーブルのインデックスが格納されます。

SHF_LINK_ORDER

このセクションは、リンカーに特別な順序の要求を追加します。この要求は、このセクションのヘッダーの sh_link フィールドが別のセクション (リンク先のセクション) を参照する場合に適用されます。このセクションを出力ファイル内のほかのセクションと結合する場合、結合対象セクションと同じ相対的な順序で現われます。同様に、リンク先のセクションは、それが結合されるセクションに現われます。リンク先のセクションは順不同でなければならず、その結果 SHF_LINK_ORDER または SHF_ORDERED を指定することはできません。

特殊な sh_link 値である SHN_BEFORE および SHN_AFTER (表 7-4 を参照) は、順序付けされるセット内のほかのすべてのセクションに対して、ソートされたセクションがそれぞれ前に付くまたは後に付くことを示します。順序付けの対象となるセクションの複数にこれらの特殊値の 1 つが存在する場合、入力ファイルが指定された順序は保存されます。

このフラグを使用する場合の典型的なものとして、アドレスの順序でテキストまたはデータセクションを参照するテーブルを構築する場合があります。

sh_link 順序付け情報が存在しない場合、出力ファイルの 1 つのセクション内にまとめられた単一入力ファイルからのセクションは、連続的になります。これらのセクションの相対順序付けは、入力ファイル内のセクションの相対順序付けと同じになります。複数の入力ファイルからの場合は、リンクコマンドで指定された順序になります。

SHF_OS_NONCONFORMING

このセクションは、不適切な動作を避けるために、標準のリンク処理規則に含まれない OS 固有の特殊処理を必要とします。このセクションが、これらのフィールドに対して sh_type 値を持つか、OS 固有の範囲内にある sh_flags ビットを含み、かつリンカーがこれらの値を認識しない場合は、このセクションを含むオブジェクトファイルは拒否され、エラーが出力されます。

SHF_GROUP

このセクションは、セクショングループのメンバー (おそらく唯一のメンバー) です。このセクションは、タイプ SHT_GROUP のセクションに参照されなければなりません。SHF_GROUP フラグは、再配置可能オブジェクト内に含まれるセクションに対してしか設定できません。詳細は、「グループセクション」を参照してください。

SHF_TLS

このセクションには、スレッド固有領域が格納されます。プロセス内の各スレッドは、このデータのインスタンスをそれぞれ別個に持ちます。詳細は、第 8 章スレッド固有領域 (TLS)を参照してください。

SHF_MASKOS

このマスクに含まれるビットはすべて、オペレーティングシステム固有のセマンティクスのために予約されています。

SHF_AMD64_LARGE

x64 用のデフォルトコンパイルモデルで使用できるのは、32 ビットのディスプレイスメントだけです。このディスプレイスメントでは、セクションのサイズ (最終的にはセグメントのサイズ) が 2G バイトに制限されます。この属性フラグは、2G バイトを超えるデータを格納できるセクションを識別します。このフラグを使えば、異なるコードモデルを使用するオブジェクトファイルのリンク処理を行えます。

SHF_AMD64_LARGE 属性フラグを含まない x64 オブジェクトファイルセクションは、小規模コードモデルを使用するオブジェクトから自由に参照できます。このフラグを含むセクションは、それよりも規模の大きいコードモデルを使用するオブジェクトからしか参照できません。たとえば、x64 中規模コードモデルのオブジェクトは、この属性フラグを含むセクション内のデータとこの属性フラグを含まないセクション内のデータを参照できます。ところが、x64 小規模コードモデルのオブジェクトは、このフラグを含まないセクション内のデータしか参照できません。

SHF_ORDERED

SHF_ORDEREDSHF_LINK_ORDER が提供する機能の古いバージョンであり、SHF_LINK_ORDER に置き換えられました。SHF_ORDERED は 2 つの異なる機能を提供します。1 つは、出力セクションを指定できる機能、もう 1 つは、リンカーから特別な順序付け要件を要求する機能です。

SHF_ORDERED セクションの sh_link フィールドはセクションのリンクリストを形成します。このリストは、自分自身を指す sh_link を持つ最終セクションで終了します。このリストにあるすべてのセクションは、リストの最終セクションの名前を使用して、出力セクションに割り当てられます。

順序付けられるセクションの sh_info エントリが同一入力ファイル内の有効セクションの場合、順序付けられるセクションは、sh_info エントリでポイントされるセクションの出力ファイル内の相対順序付けに基づいて整列されます。sh_info エントリによって指されたセクションは順不同でなければならず、その結果、SHF_LINK_ORDER または SHF_ORDERED を指定することができません。

特殊な sh_info 値である SHN_BEFORE および SHN_AFTER (表 7-4 を参照) は、順序付けされるセット内のほかのすべてのセクションに対して、ソートされたセクションがそれぞれ前に付くまたは後に付くことを示します。順序付けの対象となるセクションの複数にこれらの特殊値の 1 つが存在する場合、入力ファイルが指定された順序は保存されます。

sh_info 順序付け情報が存在しない場合、出力ファイルの 1 つのセクション内にまとめられた単一入力ファイルからのセクションは、連続的になります。これらのセクションの相対順序付けは、入力ファイル内で表示されるセクションの相対順序付けと同じになります。複数の入力ファイルからの場合は、リンクコマンドで指定された順序になります。

SHF_EXCLUDE

このセクションは、実行可能オブジェクトまたは共有オブジェクトのリンク編集への入力から除外されます。このフラグは、SHF_ALLOC フラグが設定されている場合、またはセクションに対する参照が存在する場合、無視されます。

SHF_MASKPROC

このマスクに含まれるビットはすべて、プロセッサ固有のセマンティクスのために予約されています。

セクションヘッダーの 2 つのメンバー sh_linksh_info は、セクション型に従って特殊な情報を保持します。

表 7-9 ELF sh_linksh_info の解釈

sh_type
sh_link
sh_info
SHT_DYNAMIC
関連付けられている文字列テーブルのセクションヘッダーインデックス。
0
SHT_HASH
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
0
SHT_REL

SHT_RELA

関連付けられているシンボルテーブルのセクションヘッダーインデックス。
sh_flags メンバーに SHF_INFO_LINK フラグが含まれている場合は再配置が適用されるセクションのセクションヘッダーインデックス、それ以外の場合は 0表 7-10「再配置セクション」も参照してください。
SHT_SYMTAB

SHT_DYNSYM

関連付けられている文字列テーブルのセクションヘッダーインデックス。
最後の局所シンボルのシンボルテーブルインデックス STB_LOCAL より 1 大きい。
SHT_GROUP
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
関連付けられているシンボルテーブル内のエントリの、シンボルテーブルインデックス。指定されたシンボルテーブルエントリの名前は、そのセクショングループのシグニチャを提供します。
SHT_SYMTAB_SHNDX
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
0
SHT_SUNW_cap
シンボル機能が存在する場合、関連する SHT_SUNW_capinfo テーブルのセクションヘッダーインデックス。そうでない場合は 0
機能が名前付きの文字列を参照する場合、関連する文字列テーブルのセクションヘッダーインデックス。そうでない場合は 0
SHT_SUNW_capinfo
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
動的オブジェクトの場合、関連する SHT_SUNW_capchain テーブルのセクションヘッダーインデックス。そうでない場合は 0
SHT_SUNW_symsort
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
0
SHT_SUNW_tlssort
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
0
SHT_SUNW_LDYNSYM
関連付けられている文字列テーブルのセクションヘッダーインデックス。このインデックスは、SHT_DYNSYM セクションで使用される文字列テーブルと同じです。
最後の局所シンボルのシンボルテーブルインデックス STB_LOCAL より 1 大きい。SHT_SUNW_LDYNSYM には局所シンボルしか含まれないので、sh_info はテーブル内のシンボル数に等しくなります。
SHT_SUNW_move
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
0
SHT_SUNW_COMDAT
0
0
SHT_SUNW_syminfo
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
関連付けられている .dynamic セクションのセクションヘッダーインデックス。
SHT_SUNW_verdef
関連付けられている文字列テーブルのセクションヘッダーインデックス。
セクション内のバージョン定義数。
SHT_SUNW_verneed
関連付けられている文字列テーブルのセクションヘッダーインデックス。
セクション内のバージョン依存数。
SHT_SUNW_versym
関連付けられているシンボルテーブルのセクションヘッダーインデックス。
0

セクションのマージ

SHF_MERGE セクションフラグを使って、再配置可能オブジェクト内の SHT_PROGBITS セクションにマークすることができます。表 7-8 を参照してください。このフラグによって、そのセクションがほかのオブジェクトの互換セクションとマージできることがわかります。これらの再配置可能オブジェクトをマージすることによって、それらから構築される実行可能ファイルや共有オブジェクトのサイズを減らせる可能性があります。サイズを減らすことによって、最終オブジェクトの実行時パフォーマンスが向上することもあります。

セクションに SHF_MERGE フラグが付いていることは、次のような特性があることを示します。

SHF_MERGE は、最適化できる可能性があることを示す、省略可能なフラグです。リンカーは、最適化を実行するか最適化を無視するかを選択できます。リンカーは、いずれの場合も有効な出力オブジェクトを作成します。リンカーは現在のところ、SHF_STRINGS フラグがマークされた文字列データを含むセクションだけに、セクションのマージを実装します。

SHF_STRINGS セクションフラグと一緒に SHF_MERGE フラグも設定されているときは、そのセクション内の文字列はほかの互換セクション内の文字列とマージできます。リンカーは、SHT_STRTAB 文字列テーブル .strtab.dynstr の圧縮に使用される文字列圧縮アルゴリズムを使用して、このようなセクションをマージします。

リンカーは現在のところ、バイトサイズ文字から構成され、特殊な整列制約のない文字列だけに、文字列のマージを実装します。具体的には、セクションは次の特性を備えている必要があります。


注 - リンカーの -z nocompstrtab オプションを使って文字列テーブルの圧縮を抑制できます。


特殊セクション

さまざまなセクションがプログラム情報と制御情報を保持します。次の表に示すセクションはシステムで使用されますが、これらのセクションには指定された型と属性が存在します。

表 7-10 ELF 特殊セクション

名前
種類
属性
.bss
SHT_NOBITS
SHF_ALLOC + SHF_WRITE
.comment
SHT_PROGBITS
None
.data.data1
SHT_PROGBITS
SHF_ALLOC + SHF_WRITE
.dynamic
SHT_DYNAMIC
SHF_ALLOC + SHF_WRITE
.dynstr
SHT_STRTAB
SHF_ALLOC
.dynsym
SHT_DYNSYM
SHF_ALLOC
.eh_frame_hdr
SHT_AMD64_UNWIND
SHF_ALLOC
.eh_frame
SHT_AMD64_UNWIND
SHF_ALLOC + SHF_WRITE
.fini
SHT_PROGBITS
SHF_ALLOC + SHF_EXECINSTR
.fini_array
SHT_FINI_ARRAY
SHF_ALLOC + SHF_WRITE
.got
SHT_PROGBITS
.hash
SHT_HASH
SHF_ALLOC
.init
SHT_PROGBITS
SHF_ALLOC + SHF_EXECINSTR
.init_array
SHT_INIT_ARRAY
SHF_ALLOC + SHF_WRITE
.interp
SHT_PROGBITS
「プログラムインタプリタ」を参照してください
.note
SHT_NOTE
None
.lbss
SHT_NOBITS
SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE
.ldata.ldata1
SHT_PROGBITS
SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE
.lrodata.lrodata1
SHT_PROGBITS
SHF_ALLOC + SHF_AMD64_LARGE
.plt
SHT_PROGBITS
.preinit_array
SHT_PREINIT_ARRAY
SHF_ALLOC + SHF_WRITE
.rela
SHT_RELA
None
.relname
SHT_REL
「再配置セクション」を参照してください
.relaname
SHT_RELA
「再配置セクション」を参照してください
.rodata.rodata1
SHT_PROGBITS
SHF_ALLOC
.shstrtab
SHT_STRTAB
None
.strtab
SHT_STRTAB
この表のあとの説明を参照してください。
.symtab
SHT_SYMTAB
.symtab_shndx
SHT_SYMTAB_SHNDX
.tbss
SHT_NOBITS
SHF_ALLOC + SHF_WRITE + SHF_TLS
.tdata.tdata1
SHT_PROGBITS
SHF_ALLOC + SHF_WRITE + SHF_TLS
.text
SHT_PROGBITS
SHF_ALLOC + SHF_EXECINSTR
.SUNW_bss
SHT_NOBITS
SHF_ALLOC + SHF_WRITE
.SUNW_cap
SHT_SUNW_cap
SHF_ALLOC
.SUNW_capchain
SHT_SUNW_capchain
SHF_ALLOC
.SUNW_capinfo
SHT_SUNW_capinfo
SHF_ALLOC
.SUNW_heap
SHT_PROGBITS
SHF_ALLOC + SHF_WRITE
.SUNW_ldynsym
SHT_SUNW_LDYNSYM
SHF_ALLOC
.SUNW_dynsymsort
SHT_SUNW_symsort
SHF_ALLOC
.SUNW_dymtlssort
SHT_SUNW_tlssort
SHF_ALLOC
.SUNW_move
SHT_SUNW_move
SHF_ALLOC
.SUNW_reloc
SHT_REL

SHT_RELA

SHF_ALLOC
.SUNW_syminfo
SHT_SUNW_syminfo
SHF_ALLOC
.SUNW_version
SHT_SUNW_verdef

SHT_SUNW_verneed

SHT_SUNW_versym

SHF_ALLOC
.bss

プログラムのメモリーイメージで使用される、初期化されていないデータ。システムは、プログラムが実行を開始すると 0 でデータを初期化することになっています。このセクションは、セクション型 SHT_NOBITS で示しているとおり、ファイル領域を占めません。

.comment

コメント情報 (通常、コンパイルシステムのコンポーネントが使用)。このセクションは、mcs(1) により操作できます。

.data, .data1

プログラムのメモリーイメージで使用される、初期化済みのデータ。

.dynamic

動的リンク情報。詳細は、「動的セクション」を参照してください。

.dynstr

動的リンクに必要な文字列 (もっとも一般的には、シンボルテーブルエントリに関連付けられている名前を表す文字列)。

.dynsym

動的リンクシンボルテーブル。詳細は、「シンボルテーブルセクション」を参照してください。

.eh_frame_hdr.eh_frame

スタックを戻すために使用する呼び出しフレーム情報。

.fini

このセクションを含む実行可能ファイルまたは共有オブジェクトの単一の終了関数で使用される実行可能命令。詳細は、「初期設定および終了ルーチン」を参照してください。

.fini_array

このセクションを含む実行可能ファイルまたは共有オブジェクトの単一の終了配列に使用される関数ポインタの配列。詳細は、「初期設定および終了ルーチン」を参照してください。

.got

大域オフセットテーブル。詳細は、「大域オフセットテーブル (プロセッサ固有)」を参照してください。

.hash

シンボルハッシュテーブル。詳細は、「ハッシュテーブルセクション」を参照してください。

.init

このセクションを含む実行可能ファイルまたは共有オブジェクトの単一の初期化関数で使用される実行可能命令。詳細は、「初期設定および終了ルーチン」を参照してください。

.init_array

このセクションを含む実行可能ファイルまたは共有オブジェクトの単一の初期化配列に使用される関数ポインタの配列。詳細は、「初期設定および終了ルーチン」を参照してください。

.interp

プログラムインタプリタのパス名。詳細は、「プログラムインタプリタ」を参照してください。

.lbss

x64 固有の初期化されていないデータ。このデータは .bss に似ていますが、2G バイトを超えるセクションをサポートする点が異なります。

.ldata.ldata1

x64 固有の初期化済みデータ。このデータは .data に似ていますが、2G バイトを超えるセクションをサポートする点が異なります。

.lrodata.lrodata1

x64 固有の読み取り専用データ。このデータは .rodata に似ていますが、2G バイトを超えるセクションをサポートする点が異なります。

.note

「注釈セクション」に記載された形式の情報。

.plt

プロシージャーのリンクテーブル。詳細は、「プロシージャーのリンクテーブル (プロセッサ固有)」を参照してください。

.preinit_array

このセクションを含む実行可能ファイルまたは共有オブジェクトの単一の「初期設定前」の配列に使用される関数ポインタの配列。詳細は、「初期設定および終了ルーチン」を参照してください。

.rela

特定のセクションに適用されない再配置情報。このセクションの用途の 1 つは、レジスタの再配置です。詳細は、「レジスタシンボル」を参照してください。

.relname.relaname

再配置情報 (詳細は、「再配置セクション」を参照)。再配置が存在する読み込み可能セグメントがファイルに存在する場合、これらのセクションの属性として SHF_ALLOC ビットがオンになります。そうでない場合、このビットはオフになります。慣例により、name は再配置が適用されるセクションの名前になります。したがって、.text の再配置セクションには、通常 .rel.text または .rela.text という名前が存在します。

.rodata, .rodata1

読み取り専用データ (通常はプロセスイメージの書き込み不可セグメントに使用)。詳細は、「プログラムヘッダー」を参照してください。

.shstrtab

セクション名。

.strtab

文字列。通常は、シンボルテーブルエントリに関連付けられた名前を表す文字列です。シンボル文字列テーブルが存在する読み込み可能セグメントがファイルに存在する場合、セクションの属性として SHF_ALLOC ビットがオンになります。そうでない場合、このビットはオフになります。

.symtab

シンボルテーブル (詳細は、「シンボルテーブルセクション」を参照)。シンボルテーブルが存在する読み込み可能セグメントがファイルに存在する場合、セクションの属性として SHF_ALLOC ビットがオンになります。そうでない場合、このビットはオフになります。

.symtab_shndx

このセクションには、.symtab による指定に従い、特別なシンボルテーブルセクションインデックス配列が保持されます。関連付けられたシンボルテーブルセクションに SHF_ALLOC ビットが含まれる場合、このセクションの属性も SHF_ALLOC ビットを含みます。そうでない場合、このビットはオフになります。

.tbss

このセクションには、プログラムのメモリーイメージで使用される、初期化されていないスレッド固有データが格納されます。データが新しい実行フロー用に具体化されると、システムはデータを 0 で初期化します。このセクションは、セクション型 SHT_NOBITS で示しているとおり、ファイル領域を占めません。詳細は、第 8 章スレッド固有領域 (TLS)を参照してください。

.tdata.tdata1

これらのセクションは、プログラムのメモリーイメージで使用される、初期化されたスレッド固有データを保持します。その内容のコピーは、それぞれ新しい実行フロー用にシステムによって具体化されます。詳細は、第 8 章スレッド固有領域 (TLS)を参照してください。

.text

プログラムの「テキスト」すなわち実行可能命令。

.SUNW_bss

プログラムのメモリーイメージで使用される、共有オブジェクト用の部分的に初期化されたデータ。データは実行時に初期化されます。このセクションは、セクション型 SHT_NOBITS で示しているとおり、ファイル領域を占めません。

.SUNW_cap

機能要件。詳細については、「機能セクション」を参照してください。

.SUNW_capchain

機能連鎖テーブル。詳細については、「機能セクション」を参照してください。

.SUNW_capinfo

機能シンボル情報。詳細については、「機能セクション」を参照してください。

.SUNW_heap

dldump(3C) により作成される動的実行可能ファイルのヒープ。

.SUNW_dynsymsort

.SUNW_ldynsym.dynsym の結合シンボルテーブル内のシンボルへのインデックスの配列。インデックスは、アドレスの昇順にシンボルを参照するようにソートされます。変数を表現しないシンボルまたは関数を表現しないシンボルは取り込まれません。大域シンボルとウィークシンボルが冗長な場合には、ウィークシンボルのみが残ります。詳細は、「シンボルソートセクション」を参照してください。

.SUNW_dyntlssort

.SUNW_ldynsym.dynsym の結合シンボルテーブル内のスレッド固有領域シンボルへのインデックスの配列。インデックスは、オフセットの昇順にシンボルを参照するようにソートされます。TLS 変数を表現しないシンボルは取り込まれません。大域シンボルとウィークシンボルが冗長な場合には、ウィークシンボルのみが残ります。詳細は、「シンボルソートセクション」を参照してください。

.SUNW_ldynsym

.dynsym セクションを拡張します。このセクションには、完全な .symtab セクションを使用できない状況で使用される局所関数シンボルが含まれます。リンカーは常に、.SUNW_ldynsym セクションのデータを .dynsym セクションの直前に並べて配置します。両方のセクションは常に同じ .dynstr 文字列テーブルセクションを使用します。この配置と構成により、両方のシンボルテーブルを 1 つの大きなシンボルテーブルとして処理することができます。「シンボルテーブルセクション」を参照してください。

.SUNW_move

部分的に初期化されたデータに関する追加情報。詳細は、「移動セクション」を参照してください。

.SUNW_reloc

再配置情報 (詳細は、「再配置セクション」を参照)。このセクションは再配置セクションが連結されたものであり、個々の再配置レコードに対するより良い参照のローカル性 (局所性) を与えます。再配置レコードのオフセットのみが意味があり、したがってセクション sh_info の値は 0 です。

.SUNW_syminfo

シンボルテーブルの追加情報。詳細は、「Syminfo テーブルセクション」を参照してください。

.SUNW_version

バージョン情報。詳細は、「バージョン管理セクション」を参照してください。

ドット(.) 接頭辞付きのセクション名は、システムで予約されています。これらのセクションの既存の意味が満足できるものであれば、アプリケーションはこれらのセクションを使用できます。アプリケーションは、ドット (.) 接頭辞なしの名前を使用して、システムで予約されたセクションとの競合を回避することができます。オブジェクトファイル形式では、予約されていないセクションを定義できます。オブジェクトファイルには、同じ名前を持つ複数のセクションが存在できます。

プロセッサアーキテクチャー用に予約されるセクション名は、アーキテクチャー名の省略形をセクション名の前に入れることで作成されます。セクション名の前に、e_machine に対して使用されるアーキテクチャー名を入れる必要があります。たとえば、.Foo.psect は、FOO アーキテクチャーで定義される psect セクションです。

既存の拡張セクションは、従来から使用されている名前をそのまま使用しています。

「COMDAT」セクション

「COMDAT」セクションは、セクション名 (sh_name) で一意に識別されます。リンカーが、同じセクション名の SHT_SUNW_COMDAT 型の複数のセクションを検出すると、最初のセクションが保持され、残りのセクションは破棄されます。破棄された SHT_SUNW_COMDAT セクションに適用された再配置はすべて無視されます。破棄されたセクションで定義されたシンボルもすべて削除されます。

さらに、リンカーは、コンパイラ起動時に -xF オプションが指定された場合のセクション再順序付けで使用されるセクション命名規則をサポートします。関数が .sectname%funcname という名前の SHT_SUNW_COMDAT セクションに配置された場合、保持されている最終的な SHT_SUNW_COMDAT セクションは、.sectname という名前のセクションに結合されます。この方法を使用すると、SHT_SUNW_COMDAT セクションは最終的に .text.data、またはほかのセクションに入れられます。

グループセクション

セクションの中には、相互関連のあるグループがあるものがあります。たとえば、インライン関数の out-of-line 定義では、実行可能命令を含むセクション以外にも、別の情報が必要になる場合もあります。この別の情報は、参照される文字定数を含む読み取り専用のデータセクション、1 つまたは複数のデバッギング情報セクション、およびその他の情報セクションなどです。

グループセクション間では内部参照がある場合もあります。ただし、別のオブジェクトからの重複によって、これらのセクションの 1 つが削除 (あるいは、置換) されると、このような参照は意味を成さなくなります。したがって、このようなグループをリンクされたオブジェクトに組み込んだり、オブジェクトから削除したりするときは、1 つの単位として扱います。

タイプ SHT_GROUP のセクションは、そのようなセクションのグループ化を定義します。含んでいるオブジェクトのシンボルテーブルのうちの 1 つからのシンボル名が、そのセクショングループについてのシグニチャを提供します。SHT_GROUP セクションのセクションヘッダーが、識別シンボルエントリを指定します。sh_link メンバーはそのエントリを含むシンボルテーブルセクションのセクションヘッダーインデックスを含み、sh_info メンバーはその識別エントリのシンボルテーブルインデックスを含みます。そのセクションヘッダーの sh_flags メンバーは、値 0 を含みます。そのセクションの名前 (sh_name) は指定されません。

SHT_GROUP セクションのセクションデータは、Elf32_Word エントリの配列です。最初のエントリは、フラグです。残りのエントリは、セクションヘッダーのインデックスのシーケンスです。

現在、次のフラグが定義されています。

表 7-11 ELF グループセクションのフラグ

名前
GRP_COMDAT
0x1
GRP_COMDAT

GRP_COMDATCOMDAT グループであることを示します。このグループは、同じグループシグニチャを持つものとして重複が定義されているほかのオブジェクトファイル内のほかの COMDAT グループと重複する可能性があります。その場合には、重複グループのうち 1 つのみがリンカーによって保持されます。残りのグループのメンバーは破棄されます。

SHT_GROUP セクション内のセクションヘッダーインデックスは、そのグループを構成するセクションを識別します。これらの各セクションは、SHF_GROUP フラグを sh_flags セクションヘッダーメンバー内に設定していなければなりません。リンカーがそのセクショングループを削除することを決めた場合、リンカーはそのグループのすべてのメンバーを削除します。

未決定の参照を残すことなく、シンボルテーブルの処理を最小限にしてグループの削除を行うには、次の規則に従う必要があります。

機能セクション

SHT_SUNW_cap セクションはオブジェクトの機能要件を指定します。これらの機能はオブジェクト機能と呼ばれます。このセクションは、オブジェクト内の関数の機能要件または初期化されたデータ項目も指定できます。これらの機能はシンボル機能と呼ばれます。このセクションには、次の構造の配列が含まれます。sys/elf.h を参照してください。

typedef struct {
        Elf32_Word      c_tag;
        union {
                Elf32_Word      c_val;
                Elf32_Addr      c_ptr;
        } c_un;
} Elf32_Cap;

typedef struct {
        Elf64_Xword     c_tag;
        union {
                Elf64_Xword     c_val;
                Elf64_Addr      c_ptr;
        } c_un;
} Elf64_Cap;

この種の各オブジェクトに対して、c_tagc_un の解釈を制御します。

c_val

このオブジェクトは、さまざまに解釈される整数値を表します。

c_ptr

このオブジェクトは、プログラムの仮想アドレスを表します。

次の機能タグがあります。

表 7-12 ELF 機能配列タグ

名前
c_un
CA_SUNW_NULL
0
無視される
CA_SUNW_HW_1
1
c_val
CA_SUNW_SF_1
2
c_val
CA_SUNW_HW_2
3
c_val
CA_SUNW_PLAT
4
c_ptr
CA_SUNW_MACH
5
c_ptr
CA_SUNW_ID
6
c_ptr
CA_SUNW_NULL

機能グループの最後にマークを付けます。

CA_SUNW_HW_1CA_SUNW_HW_2

ハードウェア機能の値を示します。c_val 要素は、関連ハードウェア機能を表す値を含みます。SPARC プラットフォームでは、ハードウェア機能は sys/auxv_SPARC.h に定義されます。x86 プラットフォームでは、ハードウェア機能は sys/auxv_386.h に定義されます。

CA_SUNW_SF_1

ソフトウェア機能の値を示します。c_val 要素は、sys/elf.h に定義される関連ソフトウェア機能を表す値を含みます。

CA_SUNW_PLAT

プラットフォーム名を指定します。c_ptr 要素は、プラットフォーム名を定義する、ヌル文字で終わる文字列の文字列テーブルオフセットを含みます。

CA_SUNW_MACH

マシン名を指定します。c_ptr 要素は、マシンハードウェア名を定義する、ヌル文字で終わる文字列の文字列テーブルオフセットを含みます。

CA_SUNW_ID

機能識別子名を指定します。c_ptr 要素は、識別子名を定義する、ヌル文字で終わる文字列の文字列テーブルオフセットを含みます。この要素は機能を定義しませんが、機能グループの参照に使用できる固有のシンボリック名を機能グループに割り当てます。この識別子名は、リンカーの -z symbolcap 処理の一部として局所シンボルに変換される、すべての大域シンボル名に追加されます。「オブジェクト機能のシンボル機能への変換」を参照してください。

再配置可能オブジェクトには、機能セクションを含めることができます。リンカーは、複数の入力再配置可能オブジェクトからの機能セクションを 1 つの機能セクションに統合します。リンカーを使用すると、オブジェクトの構築時に機能を定義することもできます。「機能要件の特定」を参照してください。

CA_SUNW_NULL で終了する複数の機能グループがオブジェクト内に存在できます。最初のグループ (インデックス 0 から開始) はオブジェクト機能を指定します。オブジェクト機能を定義する動的オブジェクトには、セクションに関連した PT_SUNWCAP プログラムヘッダーがあります。このプログラムヘッダーにより、実行時リンカーは、プロセスで利用可能なシステム機能に対してオブジェクトを確認できます。異なるオブジェクト機能を利用する動的オブジェクトは、フィルタを使用して柔軟な実行環境を提供できます。「機能固有の共有オブジェクト」を参照してください。

追加の機能グループはシンボル機能を指定します。シンボル機能によって、同じシンボルの複数のインスタンスがオブジェクト内に存在できます。各インスタンスは、そのインスタンスを使用するために利用できなければならない一連の機能に関連付けられています。シンボル機能が存在する場合、SHT_SUNW_cap セクションの sh_link 要素は関連の SHT_SUNW_capinfo テーブルを指します。シンボル機能を利用する動的オブジェクトでは、特定のシステム向けに最適化された関数を柔軟に有効化できます。「シンボル機能関数ファミリの作成」を参照してください。

SHT_SUNW_capinfo テーブルは関連のシンボルテーブルに相当します。SHT_SUNW_capinfo セクションの sh_link 要素は関連のシンボルテーブルを指します。機能に関連付けられた関数は、SHT_SUNW_cap セクション内の機能グループを指定する SHT_SUNW_capinfo テーブル内にインデックスを持ちます。

動的オブジェクト内では、SHT_SUNW_capinfo セクションの sh_info 要素は機能連鎖テーブルである SHT_SUNW_capchain を指します。このテーブルは、実行時リンカーが機能ファミリのメンバーの位置を特定するために使用されます。

SHT_SUNW_capinfo テーブルエントリの形式は次のとおりです。sys/elf.h を参照してください。

typedef Elf32_Word    Elf32_Capinfo;
typedef Elf64_Xword   Elf64_Capinfo;

このテーブル内の要素は、次のマクロを使用して解釈されます。sys/elf.h を参照してください。

#define ELF32_C_SYM(info)       ((info)>>8)
#define ELF32_C_GROUP(info)     ((unsigned char)(info))
#define ELF32_C_INFO(sym, grp)  (((sym)<<8)+(unsigned char)(grp))

#define ELF64_C_SYM(info)       ((info)>>32)
#define ELF64_C_GROUP(info)     ((Elf64_Word)(info))
#define ELF64_C_INFO(sym, grp)  (((Elf64_Xword)(sym)<<32)+(Elf64_Xword)(grp))

SHT_SUNW_capinfo エントリの group 要素には、このシンボルに関連する SHT_SUNW_cap テーブルのインデックスが含まれています。このようにして、この要素はシンボルを機能グループに関連付けます。予約済みのグループインデックスである CAPINFO_SUNW_GLOB は、機能インスタンスファミリの先頭のシンボルを識別して、デフォルトのインスタンスを指定します。

名前
意味
CAPINFO_SUNW_GLOB
0xff
デフォルトのシンボルを特定します。このシンボルは特定の機能に関連付けられていませんが、シンボル機能ファミリの先頭になります。

SHT_SUNW_capinfo エントリの symbol 要素には、このシンボルに関連する先頭のシンボルのインデックスが含まれます。グループとシンボルの情報を使用すると、リンカーは再配置可能オブジェクトから機能シンボルファミリを処理し、すべての出力オブジェクトに必要な機能情報を作成できます。動的オブジェクトでは、グループ CAPINFO_SUNW_GLOB を使用してタグが付けられた先頭のシンボルのシンボル要素が、SHT_SUNW_capchain テーブル内へのインデックスです。このインデックスを使用すると、実行時リンカーは機能連鎖テーブルをこのインデックスからたどり、0 エントリが検出されるまでエントリを次々に検査できます。この連鎖エントリには、機能ファミリメンバーごとにシンボルインデックスが含まれています。

シンボル機能を定義している動的オブジェクトには、DT_SUNW_CAP 動的エントリと DT_SUNW_CAPINFO 動的エントリがあります。これらのエントリは、それぞれ SHT_SUNW_cap セクションと SHT_SUNW_capinfo セクションを特定します。オブジェクトには、SHT_SUNW_capchain セクション、セクションのエントリサイズ、および合計サイズを指定する DT_SUNW_CAPCHAINDT_SUNW_CAPCHAINENT、および DT_SUNW_CAPCHAINSZ のエントリも含まれます。これらのエントリを使用すると、実行時リンカーはシンボル機能インスタンスファミリから、使用に最適なシンボルを確立できます。

オブジェクトは、オブジェクト機能のみ、シンボル機能のみ、または両方のタイプの機能を定義できます。オブジェクト機能グループはインデックス 0 から開始します。シンボル機能グループは 0 以外のインデックスから開始します。オブジェクトでシンボル機能が定義されているが、オブジェクト機能が定義されていない場合、シンボル機能の開始を示すためにインデックス 0 に 1 つの CA_SUNW_NULL エントリが存在する必要があります。

ハッシュテーブルセクション

ハッシュテーブルは、シンボルテーブルへのアクセスを提供する Elf32_Word または Elf64_Word オブジェクトから構成されます。SHT_HASH セクションは、このハッシュテーブルを提供します。ハッシュが関連付けられているシンボルテーブルは、ハッシュテーブルのセクションヘッダーの sh_link エントリに指定されます。ハッシュテーブルの構造についての説明をわかりやすくするために次の図ではラベルを表示しますが、ラベルは仕様の一部ではありません。

図 7-4 シンボルハッシュテーブル

image:ELF ハッシュテーブル情報の例。

bucket 配列には nbucket 個のエントリが存在し、chain 配列には nchain 個のエントリが存在します。インデックスは 0 から始まります。bucketchain には、シンボルテーブルインデックスを保持します。連鎖テーブルエントリは、シンボルテーブルに対応しています。シンボルテーブルエントリ数は、nchain に等しくなければなりません。したがって、シンボルテーブルインデックスにより、連鎖テーブルエントリも選択されます。

ハッシュ関数はシンボル名を受け取り、bucket インデックスの計算に使用できる値を返します。つまり、ハッシュ関数がある名前に対して値 x を返した場合、bucket [ x% nbucket ] はインデックス y を返します。このインデックスは、シンボルテーブルと連鎖テーブルの両方へのインデックスです。シンボルテーブルエントリが目的の名前でなかった場合、chain[y] は、同じハッシュ値が存在する次のシンボルテーブルエントリを返します。

目的の名前を持つシンボルテーブルエントリが選択されるか、chain エントリの値が STN_UNDEF になるまで、chain リンクをたどることができます。

ハッシュ関数を次に示します。

unsigned long
elf_Hash(const unsigned char *name)
{
    unsigned long h = 0, g;
 
        while (*name)
        {
             h = (h << 4) + *name++;
             if (g = h & 0xf0000000)
                  h ^= g >> 24;
                   h &= ~g;
        }
        return h;
}

移動セクション

一般に、ELF ファイル内では、初期設定されたデータ変数はオブジェクトファイル内で維持されます。データ変数が非常に大きく、初期設定された (ゼロ以外の) 要素が少数の場合でも、変数全体はやはりオブジェクトファイルで維持されます。

FORTRAN COMMON ブロックなど、部分的に初期化された大規模なデータ変数を含むオブジェクトは、多大なディスクスペースオーバーヘッドを引き起こす可能性があります。SHT_SUNW_move セクションは、これらのデータ変数を圧縮するメカニズムを提供します。これにより、関連するオブジェクトのディスクサイズを減らすことができます。

SHT_SUNW_move セクションは、ELF32_Move または Elf64_Move 型の複数のエントリを含みます。これらのエントリは、データ変数を一時的項目 (.bss) として定義することが可能です。これらの項目はオブジェクトファイル内のスペースは使用しませんが、実行時にはオブジェクトのメモリーイメージに反映されます。移動レコードは、完全なデータ変数を構成するためにデータについてメモリーイメージがどのように初期設定されるかを確立します。

ELF32_Move および Elf64_Move エントリは次のように定義されます。

typedef struct {
        Elf32_Lword       m_value;
        Elf32_Word        m_info;
        Elf32_Word        m_poffset;
        Elf32_Half        m_repeat;
        Elf32_Half        m_stride;
} Elf32_Move;

#define ELF32_M_SYM(info)       ((info)>>8)
#define ELF32_M_SIZE(info)      ((unsigned char)(info))
#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))

typedef struct {
        Elf64_Lword       m_value;
        Elf64_Xword       m_info;
        Elf64_Xword       m_poffset;
        Elf64_Half        m_repeat;
        Elf64_Half        m_stride;
} Elf64_Move;

#define ELF64_M_SYM(info)       ((info)>>8)
#define ELF64_M_SIZE(info)      ((unsigned char)(info))
#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))

これらの構造の要素は次のとおりです。

m_value

初期設定値で、この値はメモリーイメージへ移されます。

m_info

初期設定が適用されるものに関連するシンボルテーブルインデックス、および初期設定されるオフセットのサイズ (単位: バイト)。このメンバーの下位 8 ビットにはサイズを定義します (1、2、4、または 8)。上位ビットにはシンボルインデックスを定義します。

m_poffset

初期設定が適用される関連シンボルからの相対オフセット。

m_repeat

繰り返し回数。

m_stride

スキップの数。この値は、繰り返し初期化を行う際にスキップされる単位数を示します。1 単位は m_info で定義された初期化オブジェクトのサイズです。m_stride が 0 の場合、初期化が連続した単位に対して行われることを示します。

次のデータ定義は、通常、オブジェクトファイル内で 0x8000 バイトを消費します。

typedef struct {
        int     one;
        char    two;
} Data;

Data move[0x1000] = {
        {0, 0},       {1, '1'},     {0, 0},
        {0xf, 'F'},   {0xf, 'F'},   {0, 0},
        {0xe, 'E'},   {0, 0},       {0xe, 'E'}
};

このデータを説明するために、SHT_SUNW_move セクションを使用します。データ項目は、 .bss セクションに定義されます。このデータ項目のゼロ以外の要素は、適切な移動エントリで初期化されます。

$ elfdump -s data | fgrep move
      [17]  0x00020868 0x00008000  OBJT GLOB 0   .bss       move
$ elfdump -m data

Move Section: .SUNW_move
    symndx offset   size repeat stride   value               with respect to
      [17]      8      4      1      1 0x000000000000000001  move
      [17]     12      4      1      1 0x000000000031000000  move
      [17]     24      4      2      1 0x00000000000000000f  move
      [17]     28      4      2      1 0x000000000046000000  move
      [17]     48      4      1      1 0x00000000000000000e  move
      [17]     52      4      1      1 0x000000000045000000  move
      [17]     64      4      1      1 0x00000000000000000e  move
      [17]     68      4      1      1 0x000000000045000000  move

再配置可能オブジェクトから提供される移動セクションは連結され、リンカーにより作成されるオブジェクト内に出力されます。ただし、次の条件が成り立つ場合、リンカーは移動エントリを処理します。この処理は、移動エントリの内容を従来のデータ項目に拡張します。

注釈セクション

ベンダーやシステムエンジニアは、オブジェクトファイルに特別な情報を付加し、ほかのプログラムからその準拠性や互換性を確認できるようにする必要があることがあります。SHT_NOTE 型のセクションと PT_NOTE 型のプログラムヘッダー要素は、この目的に対して使用できます。

次の図に示すように、セクションとプログラムヘッダー要素内の注釈情報は、任意の数のエントリを保持します。64 ビットオブジェクトおよび 32 ビットオブジェクトについては、各エントリはターゲットプロセッサの形式になっている 4 バイトワードの配列です。注釈情報の構造についての説明をわかりやすくするためにラベルを図 7-6 に示しますが、ラベルは仕様の一部ではありません。

図 7-5 注釈の情報

image:ELF セクションの注釈情報。
nameszname

名前の先頭 namesz バイトには、エントリの所有者または作者を示す、ヌル文字で終わっている文字列が存在します。名前の競合を回避するための正式なメカニズムは存在しません。慣例では、ベンダーは識別子として自身の名前 (“XYZ Computer Company” など) を使用します。name がない場合、namesz の値は 0 になります。name の領域は、パッドを使用して、4 バイトに整列します。必要であれば namesz は、パッドの長さを含みません。

descszdesc

desc の先頭 descsz バイトは、注釈記述を保持します。記述子がない場合、descsz の値は 0 になります。desc の領域は、必要であればパッドを使用して、4 バイトに整列します。descsz はパットの長さを含みません。

type

注釈の解釈を示します。各エントリの作者は、自分で種類を管理します。1 つの type 値に関して複数の解釈が存在する場合があります。したがって、注釈の記述を認識するには、name と type の両方を認識しなければなりません。type は現在、負でない値でなければなりません。

次の図に示す注釈セグメントは、2 つのエントリを保持しています。

図 7-6 注釈セグメントの例

image:ELF セクションの注釈の例。

注 - システムは、名前なし (namesz == 0) の注釈情報と、長さ 0 の名前 (name[0] == '\0') を持つ注釈情報を予約していますが、現時点ではタイプは定義していません。ほかのすべての名前には、少なくとも 1 つのヌル以外の文字が存在しなければなりません。


再配置セクション

再配置は、シンボル参照をシンボル定義に関連付ける処理です。たとえば、プログラムが関数を呼び出すとき、関連付けられている呼び出し命令は、実行時に適切な宛先アドレスに制御を渡さなければなりません。再配置可能ファイルには、セクション内容の変更方法を示す情報が存在しなければなりません。この情報により、実行可能オブジェクトファイルと共有オブジェクトファイルは、プロセスのプログラムイメージに関する正しい情報を保持できます。再配置エントリは、これらのデータを保持します。

再配置エントリは、次の構造体を持つことができます。sys/elf.h を参照してください。

typedef struct {
        Elf32_Addr      r_offset;
        Elf32_Word      r_info;
} Elf32_Rel;
 
typedef struct {
        Elf32_Addr      r_offset;
        Elf32_Word      r_info;
        Elf32_Sword     r_addend;
} Elf32_Rela;

typedef struct {
        Elf64_Addr      r_offset;
        Elf64_Xword     r_info;
} Elf64_Rel;
 
typedef struct {
        Elf64_Addr      r_offset;
        Elf64_Xword     r_info;
        Elf64_Sxword    r_addend;
} Elf64_Rela;
r_offset

このメンバーは、再配置処理を適用する位置を与えます。オブジェクトファイルが異なると、このメンバーの解釈が多少異なります。

再配置可能ファイルの場合、値はセクションのオフセットを示します。再配置セクション自身はファイルの別セクションの変更方法を示します。再配置オフセットは、2 番目のセクション内の領域を指定します。

実行可能ファイルまたは共有オブジェクトの場合、値は再配置の影響を受ける領域の仮想アドレスを示します。この情報により、再配置エントリは、実行時リンカーにとって、より意味のあるものになります。

関連するプログラムによるアクセスの効率を高めるため、メンバーの解釈はオブジェクトファイルによって異なりますが、再配置タイプの意味は同じになります。

r_info

このメンバーは、再配置が行われなければならないシンボルテーブルインデックスと、適用される再配置の種類を与えます。たとえば、呼び出し命令の再配置エントリは、呼び出される関数のシンボルテーブルインデックスを保持します。インデックスが STN_UNDEF (未定義シンボルインデックス) の場合、再配置はシンボル値として 0 を使用します。

再配置の種類はプロセッサに固有です。再配置エントリの再配置の種類またはシンボルテーブルインデックスは、それぞれ ELF32_R_TYPE または ELF32_R_SYM をエントリの r_info メンバーに適用した結果です。

#define ELF32_R_SYM(info)             ((info)>>8)
#define ELF32_R_TYPE(info)            ((unsigned char)(info))
#define ELF32_R_INFO(sym, type)       (((sym)<<8)+(unsigned char)(type))

#define ELF64_R_SYM(info)             ((info)>>32)
#define ELF64_R_TYPE(info)            ((Elf64_Word)(info))
#define ELF64_R_INFO(sym, type)       (((Elf64_Xword)(sym)<<32)+ \ 
                                        (Elf64_Xword)(type))

64 ビット SPARC Elf64_Rela 構造の場合、r_info フィールドはさらに 8 ビットの識別子と 24 ビットの付随的なデータに分割されます。既存の再配置タイプの場合、データフィールドはゼロになります。これに対し、新しい再配置タイプの場合には、データビットが使用される可能性があります。

#define ELF64_R_TYPE_DATA(info)       (((Elf64_Xword)(info)<<32)>>40)
#define ELF64_R_TYPE_ID(info)         (((Elf64_Xword)(info)<<56)>>56)
#define ELF64_R_TYPE_INFO(data, type) (((Elf64_Xword)(data)<<8)+ \ 
                                        (Elf64_Xword)(type))
r_addend

このメンバーは、再配置可能フィールドに格納される値の計算に使用される定数加数を指定します。

Rela エントリには、明示的加数が含まれます。Rel エントリには、変更される位置に暗黙の加数が存在します。32 ビット SPARC では、Elf32_Rela 再配置エントリのみを使用します。64 ビット SPARC および 64 ビット x86 では、 Elf64_Rela 再配置エントリのみを使用します。したがって、r_addend メンバーは再配置加数として機能します。x86 は、Elf32_Rel 再配置エントリのみを使用します。再配置対象のフィールドは、加数を保持します。すべての場合において、加数と計算された結果は同じバイト順序を使用します。

再配置セクションは、ほかに 2 つのセクションを参照することがあります。 1 つは sh_info セクションヘッダーエントリにより示されるシンボルテーブルで、もう 1 つは sh_link セクションヘッダーエントリにより示される変更対象のセクションです。「セクション」 に、各セクションの関係を示します。再配置オブジェクトに再配置セクションが存在するが、実行可能ファイルや共有オブジェクトが任意の場合は、sh_info エントリが必要です。再配置オフセットが存在すれば、再配置を実行できます。

再配置型 (プロセッサ固有)

再配置エントリには、次の図に示す命令およびデータフィールドの変更方法が記述されます。ビット番号は、下隅に示されています。

SPARC プラットフォームの場合、再配置エントリはバイト (byte8)、ハーフワード (half16) またはワードに適用されます。

image:32 ビットの再配置エントリ。

64 ビット SPARC と x64 では、再配置は拡張ワード (xword64) にも適用されます。

image:64 ビットの再配置エントリ。

x86 の場合、再配置エントリはワード (word32) に適用されます。

image:x86 再配置エントリ

word32 は、任意バイト整列が存在する 4 バイトを占める 32 ビットフィールドを指定します。これらの値は、x86 アーキテクチャーにおけるほかのワード値と同じバイト順序を使用します。

image:x86 再配置エントリ

いずれの場合でも r_offset 値は、影響が与えられる領域の先頭バイトのオフセットまたは仮想アドレスを指定します。再配置タイプは、変更されるビットと、これらのビットの値の計算方法を指定します。

次の再配置型の計算では、操作により、再配置可能ファイルが実行可能ファイルまたは共有オブジェクトファイルに変換されることが仮定されています。概念上、リンカーは 1 つまたは複数の再配置可能ファイルを併合して出力します。リンカーは、まず入力ファイルの結合/配置方法を決めます。次に、シンボルの値を更新し、再配置を実行します。実行可能オブジェクトファイルと共有オブジェクトファイルに適用される再配置は類似しており、同じ結果を実現します。このセクションの表では、次の表記が使用されています。

A

再配置可能フィールドの値を計算するために使用される加数。

B

実行時に共有オブジェクトがメモリーに読み込まれるベースアドレス。一般的に、共有オブジェクトファイルは、ベース仮想アドレス 0 で作成されます。ただし、共有オブジェクトの実行アドレスは異なります。「プログラムヘッダー」を参照してください。

G

実行時に再配置エントリのシンボルのアドレスが存在する大域オフセットテーブルへのオフセット。「大域オフセットテーブル (プロセッサ固有)」を参照してください。

GOT

大域オフセットテーブルのアドレス。「大域オフセットテーブル (プロセッサ固有)」を参照してください。

L

シンボルに対するプロシージャーのリンクテーブルエントリのセクションオフセットまたはアドレス。「プロシージャーのリンクテーブル (プロセッサ固有)」を参照してください。

P

再配置される領域のセクションオフセットまたはアドレス (r_offset を使用して計算)。

S

インデックスが再配置エントリ内に存在するシンボルの値。

Z

インデックスが再配置エントリ内に存在するシンボルのサイズ。

SPARC: 再配置型

次の表に示すフィールド名は、再配置型がオーバーフローを検査するかどうかを通知します。計算される再配置値は意図したフィールドより大きい場合があり、再配置型によっては値の適合を検証 (V) したり結果を切り捨てたり (T) することがあります。たとえば、V-simm13 は、計算された値が simm13 フィールドの外部に 0 以外の有意ビットを持つことがないことを意味します。

表 7-13 SPARC: ELF 再配置型

名前
フィールド
計算
R_SPARC_NONE
0
None
None
R_SPARC_8
1
V-byte8
S + A
R_SPARC_16
2
V-half16
S + A
R_SPARC_32
3
V-word32
S + A
R_SPARC_DISP8
4
V-byte8
S + A - P
R_SPARC_DISP16
5
V-half16
S + A - P
R_SPARC_DISP32
6
V-disp32
S + A - P
R_SPARC_WDISP30
7
V-disp30
(S + A - P) >> 2
R_SPARC_WDISP22
8
V-disp22
(S + A - P) >> 2
R_SPARC_HI22
9
T-imm22
(S + A) >> 10
R_SPARC_22
10
V-imm22
S + A
R_SPARC_13
11
V-simm13
S + A
R_SPARC_LO10
12
T-simm13
(S + A) & 0x3ff
R_SPARC_GOT10
13
T-simm13
G & 0x3ff
R_SPARC_GOT13
14
V-simm13
G
R_SPARC_GOT22
15
T-simm22
G >> 10
R_SPARC_PC10
16
T-simm13
(S + A - P) & 0x3ff
R_SPARC_PC22
17
V-disp22
(S + A - P) >> 10
R_SPARC_WPLT30
18
V-disp30
(L + A - P) >> 2
R_SPARC_COPY
19
None
この表のあとの説明を参照してください。
R_SPARC_GLOB_DAT
20
V-word32
S + A
R_SPARC_JMP_SLOT
21
None
この表のあとの説明を参照してください。
R_SPARC_RELATIVE
22
V-word32
B + A
R_SPARC_UA32
23
V-word32
S + A
R_SPARC_PLT32
24
V-word32
L + A
R_SPARC_HIPLT22
25
T-imm22
(L + A) >> 10
R_SPARC_LOPLT10
26
T-simm13
(L + A) & 0x3ff
R_SPARC_PCPLT32
27
V-word32
L + A - P
R_SPARC_PCPLT22
28
V-disp22
(L + A - P) >> 10
R_SPARC_PCPLT10
29
V-simm13
(L + A - P) & 0x3ff
R_SPARC_10
30
V-simm10
S + A
R_SPARC_11
31
V-simm11
S + A
R_SPARC_HH22
34
V-imm22
(S + A) >> 42
R_SPARC_HM10
35
T-simm13
((S + A) >> 32) & 0x3ff
R_SPARC_LM22
36
T-imm22
(S + A) >> 10
R_SPARC_PC_HH22
37
V-imm22
(S + A - P) >> 42
R_SPARC_PC_HM10
38
T-simm13
((S + A - P) >> 32) & 0x3ff
R_SPARC_PC_LM22
39
T-imm22
(S + A - P) >> 10
R_SPARC_WDISP16
40
V-d2/disp14
(S + A - P) >> 2
R_SPARC_WDISP19
41
V-disp19
(S + A - P) >> 2
.R_SPARC_7
43
V-imm7
S + A
R_SPARC_5
44
V-imm5
S + A
R_SPARC_6
45
V-imm6
S + A
R_SPARC_HIX22
48
V-imm22
((S + A) ^ 0xffffffffffffffff) >> 10
R_SPARC_LOX10
49
T-simm13
((S + A) & 0x3ff) | 0x1c00
R_SPARC_H44
50
V-imm22
(S + A) >> 22
R_SPARC_M44
51
T-imm10
((S + A) >> 12) & 0x3ff
R_SPARC_L44
52
T-imm13
(S + A) & 0xfff
R_SPARC_REGISTER
53
V-word32
S + A
R_SPARC_UA16
55
V-half16
S + A
R_SPARC_GOTDATA_HIX22
80
V-imm22
((S + A - GOT) >> 10) ^ ((S + A - GOT) >> 31)
R_SPARC_GOTDATA_LOX10
81
T-imm13
((S + A - GOT) & 0x3ff) | (((S + A - GOT) >> 31) & 0x1c00)
R_SPARC_GOTDATA_OP_HIX22
82
T-imm22
(G >> 10) ^ (G >> 31)
R_SPARC_GOTDATA_OP_LOX10
83
T-imm13
(G & 0x3ff) | ((G >> 31) & 0x1c00)
R_SPARC_GOTDATA_OP
84
Word32
この表のあとの説明を参照してください。
R_SPARC_SIZE32
86
V-word32
Z + A

注 - スレッド固有領域の参照に使用できる再配置はほかにも存在します。これらの再配置については、第 8 章スレッド固有領域 (TLS)で説明しています。


いくつかの再配置型には、単純な計算を超えたセマンティクスが存在します。

R_SPARC_GOT10

R_SPARC_LO10 に似ていますが、シンボルの GOT エントリのアドレスを参照する点が異なります。また、 R_SPARC_GOT10 は、大域オフセットテーブルの作成をリンカーに指示します。

R_SPARC_GOT13

R_SPARC_13 に似ていますが、シンボルの GOT エントリのアドレスを参照する点が異なります。また、 R_SPARC_GOT13 は、大域オフセットテーブルの作成をリンカーに指示します。

R_SPARC_GOT22

R_SPARC_22 に似ていますが、シンボルの GOT エントリのアドレスを参照する点が異なります。また、 R_SPARC_GOT22 は、大域オフセットテーブルの作成をリンカーに指示します。

R_SPARC_WPLT30

R_SPARC_WDISP30 に似ていますが、シンボルのプロシージャーリンクテーブルエントリのアドレスを参照する点が異なります。また、R_SPARC_WPLT30 は、プロシージャーのリンクテーブル作成をリンカーに指示します。

R_SPARC_COPY

リンカーは、この再配置型を作成して、動的実行可能ファイルが読み取り専用のテキストセグメントを保持できるようにします。この再配置型のオフセットメンバーは、書き込み可能セグメントの位置を参照します。シンボルテーブルインデックスは、現オブジェクトファイルと共有オブジェクトの両方に存在する必要があるシンボルを指定します。実行時、実行時リンカーは共有オブジェクトのシンボルに関連付けられているデータを、オフセットで指定されている位置にコピーします。「コピー再配置」を参照してください。

R_SPARC_GLOB_DAT

R_SPARC_32 に似ていますが、再配置は GOT エントリを指定されたシンボルのアドレスに設定する点が異なります。この特殊な再配置型を使うと、シンボルと GOT エントリの対応付けを判定できます。

R_SPARC_JMP_SLOT

リンカーは、動的オブジェクトが遅延結合を提供できるようにするため、この再配置型を作成します。この再配置型のオフセットメンバーは、プロシージャーのリンクテーブルエントリの位置を与えます。実行時リンカーは、プロシージャーのリンクテーブルエントリを変更して指定シンボルアドレスに制御を渡します。

R_SPARC_RELATIVE

リンカーは、動的オブジェクト用にこの再配置型を作成します。この再配置型のオフセットメンバーは、相対アドレスを表す値が存在する、共有オブジェクト内の位置を与えます。実行時リンカーは共有オブジェクトが読み込まれる仮想アドレスに相対アドレスを加算することで、対応する仮想アドレスを計算します。この型に対する再配置エントリは、シンボルテーブルインデックスに対して値 0 を指定する必要があります。

R_SPARC_UA32

R_SPARC_32 に似ていますが、整列されていないワードを参照する点が異なります。再配置されるワードは、任意整列が存在する 4 つの別個のバイトとして処理されなければなりません (アーキテクチャーの要求に従って整列されるワードとしては処理されません)。

R_SPARC_LM22

R_SPARC_HI22 に似ていますが、妥当性検査ではなく切り捨てを行う点が異なります。

R_SPARC_PC_LM22

R_SPARC_PC22に似ていますが、妥当性検査ではなく切り捨てを行う点が異なります。

R_SPARC_HIX22

64 ビットアドレス空間の最上位 4G バイトに限定される実行可能ファイルに対して R_SPARC_LOX10 とともに使用されます。R_SPARC_HI22 に似ていますが、リンク値の 1 の補数を与えます。

R_SPARC_LOX10

R_SPARC_HIX22 とともに使用されます。R_SPARC_LO10 に似ていますが、必ずリンク値のビット 10 からビット 12 までを設定します。

R_SPARC_L44

再配置型 R_SPARC_H44 および R_SPARC_M44 とともに使用され、44 ビット絶対アドレス指定モデルを生成します。

R_SPARC_REGISTER

レジスタシンボルの初期化に使用されます。この再配置型のオフセットメンバーには、初期化されるレジスタ番号が存在します。このレジスタに対応するレジスタシンボルが必要です。このシンボルの種類は SHN_ABS です。

R_SPARC_GOTDATA_OP_HIX22R_SPARC_GOTDATA_OP_LOX10R_SPARC_GOTDATA_OP

これらの再配置はコード変換に対応したものです。

64 ビット SPARC: 再配置型

再配置計算に使用される次の表記は、64 ビット SPARC 固有のものです。

O

再配置可能フィールドの値を計算するために使用される二次的な加数。この加数は、ELF64_R_TYPE_DATA マクロを適用することにより r_info フィールドから抽出されます。

次の表に示す再配置型は、32 ビット SPARC 用に定義された再配置型を拡張または変 更します。「SPARC: 再配置型」を参照してください。

表 7-14 64 ビット SPARC: ELF 再配置型

名前
フィールド
計算
R_SPARC_HI22
9
V-imm22
(S + A) >> 10
R_SPARC_GLOB_DAT
20
V-xword64
S + A
R_SPARC_RELATIVE
22
V-xword64
B + A
R_SPARC_64
32
V-xword64
S + A
R_SPARC_OLO10
33
V-simm13
((S + A) & 0x3ff) + O
R_SPARC_DISP64
46
V-xword64
S + A - P
R_SPARC_PLT64
47
V-xword64
L + A
R_SPARC_REGISTER
53
V-xword64
S + A
R_SPARC_UA64
54
V-xword64
S + A
R_SPARC_H34
85
V-imm22
(S + A) >> 12
R_SPARC_SIZE64
87
V-xword64
Z + A

次の再配置型には、単純な計算を超えたセマンティクスが存在します。

R_SPARC_OLO10

R_SPARC_LO10 に似ていますが、符号付き13 ビット即値フィールドを十分に使用するために余分なオフセットが追加される点が異なります。

32 ビット x86: 再配置型

次の表に、32 ビット x86 用に定義された再配置を示します。

表 7-15 32 ビット x86: ELF 再配置型

名前
フィールド
計算
R_386_NONE
0
None
None
R_386_32
1
word32
S + A
R_386_PC32
2
word32
S + A - P
R_386_GOT32
3
word32
G + A
R_386_PLT32
4
word32
L + A - P
R_386_COPY
5
None
この表のあとの説明を参照してください。
R_386_GLOB_DAT
6
word32
S
R_386_JMP_SLOT
7
word32
S
R_386_RELATIVE
8
word32
B + A
R_386_GOTOFF
9
word32
S + A - GOT
R_386_GOTPC
10
word32
GOT + A - P
R_386_32PLT
11
word32
L + A
R_386_16
20
word16
S + A
R_386_PC16
21
word16
S + A - P
R_386_8
22
word8
S + A
R_386_PC8
23
word8
S + A - P
R_386_SIZE32
38
word32
Z + A

注 - スレッド固有領域の参照に使用できる再配置はほかにも存在します。これらの再配置については、第 8 章スレッド固有領域 (TLS)で説明しています。


いくつかの再配置型には、単純な計算を超えたセマンティクスが存在します。

R_386_GOT32

GOT のベースからシンボルの GOT エントリまでの距離を計算します。この再配置型はまた、大域オフセットテーブルを作成するようにリンカーに指示します。

R_386_PLT32

シンボルのプロシージャーのリンクテーブルエントリのアドレスを計算し、かつプロシージャーのリンクテーブルを作成するようにリンカーに指示します。

R_386_COPY

リンカーは、この再配置型を作成して、動的実行可能ファイルが読み取り専用のテキストセグメントを保持できるようにします。この再配置型のオフセットメンバーは、書き込み可能セグメントの位置を参照します。シンボルテーブルインデックスは、現オブジェクトファイルと共有オブジェクトの両方に存在する必要があるシンボルを指定します。実行時、実行時リンカーは共有オブジェクトのシンボルに関連付けられているデータを、オフセットで指定されている位置にコピーします。「コピー再配置」を参照してください。

R_386_GLOB_DAT

GOT エントリを、指定されたシンボルのアドレスに設定します。この特殊な再配置型を使うと、シンボルと GOT エントリの対応付けを判定できます。

R_386_JMP_SLOT

リンカーは、動的オブジェクトが遅延結合を提供できるようにするため、この再配置型を作成します。この再配置型のオフセットメンバーは、プロシージャーのリンクテーブルエントリの位置を与えます。実行時リンカーは、プロシージャーのリンクテーブルエントリを変更して指定シンボルアドレスに制御を渡します。

R_386_RELATIVE

リンカーは、動的オブジェクト用にこの再配置型を作成します。この再配置型のオフセットメンバーは、相対アドレスを表す値が存在する、共有オブジェクト内の位置を与えます。実行時リンカーは共有オブジェクトが読み込まれる仮想アドレスに相対アドレスを加算することで、対応する仮想アドレスを計算します。この型に対する再配置エントリは、シンボルテーブルインデックスに対して値 0 を指定する必要があります。

R_386_GOTOFF

シンボルの値と GOT のアドレスの差を計算します。この再配置型はまた、大域オフセットテーブルを作成するようにリンカーに指示します。

R_386_GOTPC

R_386_PC32 に似ていますが、計算を行う際に GOT のアドレスを使用する点が異なります。この再配置で参照されるシンボルは、通常 _GLOBAL_OFFSET_TABLE_ です。 この再配置型はまた、大域オフセットテーブルを作成するようにリンカーに指示します。

x64: 再配置型

次の表に、x64 用に定義された再配置を示します。

表 7-16 x64: ELF 再配置型

名前
フィールド
計算
R_AMD64_NONE
0
None
None
R_AMD64_64
1
word64
S + A
R_AMD64_PC32
2
word32
S + A - P
R_AMD64_GOT32
3
word32
G + A
R_AMD64_PLT32
4
word32
L + A - P
R_AMD64_COPY
5
None
この表のあとの説明を参照してください。
R_AMD64_GLOB_DAT
6
word64
S
R_AMD64_JUMP_SLOT
7
word64
S
R_AMD64_RELATIVE
8
word64
B + A
R_AMD64_GOTPCREL
9
word32
G + GOT + A - P
R_AMD64_32
10
word32
S + A
R_AMD64_32S
11
word32
S + A
R_AMD64_16
12
word16
S + A
R_AMD64_PC16
13
word16
S + A - P
R_AMD64_8
14
word8
S + A
R_AMD64_PC8
15
word8
S + A - P
R_AMD64_PC64
24
word64
S + A - P
R_AMD64_GOTOFF64
25
word64
S + A - GOT
R_AMD64_GOTPC32
26
word32
GOT + A + P
R_AMD64_SIZE32
32
word32
Z + A
R_AMD64_SIZE64
33
word64
Z + A

注 - スレッド固有領域の参照に使用できる再配置はほかにも存在します。これらの再配置については、第 8 章スレッド固有領域 (TLS)で説明しています。


これらの再配置型のほとんどの特別なセマンティクスは、x86 で使用されているものと同じです。いくつかの再配置型には、単純な計算を超えたセマンティクスが存在します。

R_AMD64_GOTPCREL

この再配置のセマンティクスは R_AMD64_GOT32 または等しい R_386_GOTPC 再配置と異なります。x64 アーキテクチャーは、命令ポインタに対して相対的なアドレス指定モードを提供します。したがって、アドレスは 1 つの命令で GOT から読み込むことができます。

R_AMD64_GOTPCREL 再配置の計算は、シンボルのアドレスを指定した GOT 内の位置と再配置を適用する位置の間の差を提供します。

R_AMD64_32

計算値は 32 ビットに切り捨てられます。リンカーは、再配置のために生成された値が元の 64 ビット値にゼロ拡張されていることを確認します。

R_AMD64_32S

計算値は 32 ビットに切り捨てられます。リンカーは、再配置のために生成された値が元の 64 ビット値に符号拡張されていることを確認します。

R_AMD64_8R_AMD64_16R_AMD64_PC16R_AMD64_PC8

これらの再配置は x64 ABI には準拠していませんが、文書化するためにここに追加しておきます。R_AMD64_8 再配置は、計算値を 8 ビットに切り詰めます。R_AMD64_16 再配置は、計算値を 16 ビットに切り詰めます。

文字列テーブルセクション

文字列テーブルセクションは、ヌル文字で終了する一連の文字 (一般に文字列と呼ばれている) を保持します。オブジェクトファイルは、これらの文字列を使用してシンボルとセクション名を表します。文字列をインデックスに使用して、文字列テーブルセクションを参照します。

先頭バイト (インデックス 0) は、ヌル文字を保持します。同様に、文字列テーブルの最後のバイトは、ヌル文字を保持します。したがって、すべての文字列は確実にヌル文字で終了します。したがって、すべての文字列は確実にヌル文字で終了します。インデックスが 0 の文字列は、名前を指定しないかヌル文字の名前を指定します (状況に依存する)。

空の文字列テーブルセクションが許可されており、セクションヘッダーの sh_size メンバーに 0 が入ります。0 以外のインデックスは、空の文字列テーブルに対して無効です。

セクションヘッダーの sh_name メンバーは、セクションヘッダー文字列テーブルセクションへのインデックスを保持します。セクションヘッダー文字列テーブルは、ELF ヘッダーの e_shstrndx メンバーで示されます。次の図は、25 バイトの文字列テーブルと、さまざまなインデックスに関連付けられている文字列を示しています。

図 7-7 ELF 文字列テーブル

image:ELF 文字列テーブルの例。

次の表に、上の図に示した文字列テーブルの文字列を示しています。

表 7-17 ELF 文字列テーブルインデックス

索引
文字列
0
None
1
name
7
Variable
11
able
16
able
24
ヌル文字列

例で示しているとおり、文字列テーブルインデックスはセクションのすべてのバイトを参照できます。文字列は 2 回以上出現可能です。部分文字列に対する参照は存在可能です。単一文字列は複数回参照可能です。参照されない文字列も許可されます。

シンボルテーブルセクション

オブジェクトファイルのシンボルテーブルには、プログラムのシンボル定義とシンボル参照の検索と再配置に必要となる情報が格納されます。シンボルテーブルインデックスは、この配列への添字です。インデックス 0 はシンボルテーブルの先頭エントリを指定し、また未定義シンボルインデックスとして機能します。表 7-21 を参照してください。

シンボルテーブルエントリの形式は、次のとおりです。sys/elf.h を参照してください。

typedef struct {
        Elf32_Word      st_name;
        Elf32_Addr      st_value;
        Elf32_Word      st_size;
        unsigned char   st_info;
        unsigned char   st_other;
        Elf32_Half      st_shndx;
} Elf32_Sym;

typedef struct {
        Elf64_Word      st_name;
        unsigned char   st_info;
        unsigned char   st_other;
        Elf64_Half      st_shndx;
        Elf64_Addr      st_value;
        Elf64_Xword     st_size;
} Elf64_Sym;
st_name

オブジェクトファイルのシンボル文字列テーブルへのインデックス (シンボル名の文字表現を保持)。値が 0 以外の場合、その値はシンボル名を与える文字列テーブルインデックスを表します。値が 0 の場合、シンボルテーブルエントリに名前は存在しません。

st_value

関連付けられているシンボルの値。この値は、状況に応じて絶対値またはアドレスを表します。「シンボル値」を参照してください。

st_size

多くのシンボルは、関連付けられているサイズを持っています。たとえば、データオブジェクトのサイズは、オブジェクトに存在するバイト数です。このメンバーは、シンボルがサイズを持っていない場合またはサイズが不明な場合、値 0 を保持します。

st_info

シンボルの種類および結び付けられる属性。値と意味のリストを、表 7-18 に示します。次のコードは、値の処理方法を示します。sys/elf.h を参照してください。

#define ELF32_ST_BIND(info)          ((info) >> 4)
#define ELF32_ST_TYPE(info)          ((info) & 0xf)
#define ELF32_ST_INFO(bind, type)    (((bind)<<4)+((type)&0xf))

#define ELF64_ST_BIND(info)          ((info) >> 4)
#define ELF64_ST_TYPE(info)          ((info) & 0xf)
#define ELF64_ST_INFO(bind, type)    (((bind)<<4)+((type)&0xf))
st_other

シンボルの可視性。値と意味のリストを、表 7-20 に示します。次のコードは、32 ビットオブジェクトと 64 ビットオブジェクトの両方の値を操作する方法を示しています。その他のビットは 0 に設定され、特に意味はありません。

#define ELF32_ST_VISIBILITY(o)       ((o)&0x3)
#define ELF64_ST_VISIBILITY(o)       ((o)&0x3)
st_shndx

すべてのシンボルテーブルエントリは、何らかのセクションに関して定義されます。このメンバーは、該当するセクションヘッダーテーブルインデックスを保持します。いくつかのセクションインデックスは、特別な意味を示します。表 7-4 を参照してください。

このメンバーに SHN_XINDEX が含まれる場合は、実際のセクションヘッダーインデックスが大きすぎてこのフィールドに入りません。実際の値は、タイプ SHT_SYMTAB_SHNDX の関連するセクション内に存在します。

シンボルのバインディングは、st_info フィールドで決定されますが、これにより、リンクの可視性と動作が決定します。

表 7-18 ELF シンボルのバインディング、(ELF32_ST_BINDELF64_ST_BIND)

名前
STB_LOCAL
0
STB_GLOBAL
1
STB_WEAK
2
STB_LOOS
10
STB_HIOS
12
STB_LOPROC
13
STB_HIPROC
15
STB_LOCAL

局所シンボル。局所シンボルは、局所シンボルの定義が存在するオブジェクトファイルの外部では見えません。同じ名前の局所シンボルは、互いに干渉することなく複数のファイルに存在できます。

STB_GLOBAL

大域シンボル。大域シンボルは、結合されるすべてのオブジェクトファイルで見ることができます。あるファイルの大域シンボルの定義は、その大域シンボルへの別ファイルの未定義参照を解決します。

STB_WEAK

ウィークシンボル。ウィークシンボルは大域シンボルに似ていますが、ウィークシンボルの定義の優先順位は大域シンボルの定義より低いです。

STB_LOOS - STB_HIOS

この範囲の値 (両端の値を含む) は、オペレーティングシステム固有のセマンティクスのために予約されています。

STB_LOPROC - STB_HIPROC

この範囲の値は、プロセッサ固有のセマンティクスのために予約されています。

大域シンボルとウィークシンボルは、主に 2 つの点で異なります。


注 - ウィークシンボルは、主にシステムソフトウェアでの使用を意図したものです。アプリケーションプログラムでの使用は推奨されません。


各シンボルテーブルにおいて、STB_LOCAL 結合を持つすべてのシンボルは、ウィークシンボルと大域シンボルの前に存在します。「セクション」に記述されているとおり、シンボルテーブルセクションの sh_info セクションヘッダーメンバーは、最初のローカルではないシンボルに対するシンボルテーブルインデックスを保持します。

シンボルのタイプは st_info フィールドで指定され、これにより、関連付けられた実体の一般的な分類が決定されます。

表 7-19 ELF シンボルのタイプ (ELF32_ST_TYPEELF64_ST_TYPE)

名前
STT_NOTYPE
0
STT_OBJECT
1
STT_FUNC
2
STT_SECTION
3
STT_FILE
4
STT_COMMON
5
STT_TLS
6
STT_LOOS
10
STT_HIOS
12
STT_LOPROC
13
STT_SPARC_REGISTER
13
STT_HIPROC
15
STT_NOTYPE

シンボルの種類は指定されません。

STT_OBJECT

シンボルは、データオブジェクト (変数や配列など) と関連付けられています。

STT_FUNC

シンボルは、関数またはほかの実行可能コードに関連付けられています。

STT_SECTION

シンボルは、セクションに関連付けられています。この種類のシンボルテーブルエントリは主に再配置を行うために存在しており、通常、STB_LOCAL に結び付けられています。

STT_FILE

慣例により、シンボルの名前はオブジェクトファイルに対応するソースファイルの名前を与えます。ファイルシンボルは STB_LOCAL に結び付けられており、セクションインデックスは SHN_ABS です。このシンボルは、存在する場合、ファイルのほかの STB_LOCAL シンボルの前に存在します。

SHT_SYMTAB のシンボルインデックス 1 は、そのオブジェクトファイルを表す STT_FILE シンボルです。慣例により、このシンボルの後にはファイル STT_SECTION シンボルが続きます。これらのセクションシンボルの後には、ローカルになった大域シンボルが続きます。

STT_COMMON

このシンボルは、初期設定されていない共通ブロックを表します。このシンボルは、STT_OBJECT とまったく同じに扱われます。

STT_TLS

シンボルは、スレッド固有領域の実体を指定します。定義されている場合、実際のアドレスではなく、シンボルに割り当てられたオフセットを提供します。

スレッドローカルストレージの再配置では、タイプが STT_TLS のシンボルしか参照できません。割り当て可能なセクションからタイプが STT_TLS のシンボルを参照するには、特別なスレッドローカルストレージ再配置を使用するしか方法がありません。詳細は、第 8 章スレッド固有領域 (TLS)を参照してください。割り当てができないセクションからタイプが STT_TLS のシンボルを参照する際には、この制限はありません。

STT_LOOS - STT_HIOS

この範囲の値 (両端の値を含む) は、オペレーティングシステム固有のセマンティクスのために予約されています。

STT_LOPROC - STT_HIPROC

この範囲の値は、プロセッサ固有のセマンティクスのために予約されています。

シンボルの可視性は、その st_other フィールドで決まります。この可視性は、再配置可能オブジェクトで指定できます。シンボルの可視性により、シンボルが実行可能ファイルまたは共有オブジェクトの一部になった後のシンボルへのアクセス方法が定義されます。

表 7-20 ELF シンボルの可視性

名前
STV_DEFAULT
0
STV_INTERNAL
1
STV_HIDDEN
2
STV_PROTECTED
3
STV_EXPORTED
4
STV_SINGLETON
5
STV_ELIMINATE
6
STV_DEFAULT

STV_DEFAULT 属性を持つシンボルの可視性は、シンボルの結合タイプで指定されたものになります。大域シンボルおよびウィークシンボルは、それらの定義するコンポーネント (実行可能ファイルまたは共有オブジェクト) の外から見ることができます。局所シンボルは、「隠されて」います。大域シンボルおよびウィークシンボルは、横取りすることもできます。別のコンポーネントの同じ名前の定義によってこれらのシンボルに割り込むこともできます。

STV_PROTECTED

現在のコンポーネント内で定義されたシンボルは、それがほかのコンポーネント内で参照可能であるが横取り可能ではない場合、保護されています。定義コンポーネント内からシンボルへの参照など、あらゆる参照について、コンポーネント内の定義に解決する必要があります。この解決は、シンボル定義がデフォルト規則によって割り込みを行う別のコンポーネント内に存在する場合も、実行する必要があります。STB_LOCAL 結合を持つシンボルは、STV_PROTECTED 可視性を持ちません。

STV_HIDDEN

現在のコンポーネント内で定義されたシンボルは、その名前がほかのコンポーネントから参照することができない場合、「隠されて」います。そのようなシンボルは、保護される必要があります。この属性は、コンポーネントの外部インタフェースの管理に使用されます。そのようなシンボルによって指定されたオブジェクトは、そのアドレスが外部に渡された場合でも、ほかのコンポーネントから参照可能です。

再配置可能オブジェクトに含まれた「隠された」シンボルは、そのオブジェクトが実行可能ファイルまたは共有オブジェクトに含まれる時には、削除されるか STB_LOCAL 結合に変換されます。

STV_INTERNAL

この可視性の属性は、現在予約されています。

STV_EXPORTED

この可視性属性によって、シンボルのスコープが大域に維持されます。ほかのどのようなシンボル可視性テクニックを使っても、この可視性を降格または削除することはできません。STB_LOCAL 結合を持つシンボルは、STV_EXPORTED 可視性を持ちません。

STV_SINGLETON

この可視性属性によって、シンボルのスコープが大域に維持され、プロセス内のすべての参照はシンボル定義の 1 つのインスタンスだけにバインドされます。ほかのどのようなシンボル可視性テクニックを使っても、この可視性を降格または削除することはできません。STB_LOCAL 結合を持つシンボルは、STV_SINGLETON 可視性を持ちません。STV_SINGLETON に直接バインドすることはできません。

STV_ELIMINATE

この可視性属性は STV_HIDDEN を継承します。現在のコンポーネント内でこの属性が定義されたシンボルは、ほかのコンポーネントから見えません。このシンボルは、そのコンポーネントを使用する動的実行可能ファイルまたは共有オブジェクトのシンボルテーブルには書き込まれません。

STV_SINGLETON 可視性属性は、リンク編集中、実行可能ファイルまたは共有オブジェクト内のシンボルの解決に影響する可能性があります。プロセス内の参照には、シングルトンの 1 つのインスタンスだけをバインドできます。

STV_SINGLETONSTV_DEFAULT 可視性属性と一緒に使用できますが、STV_SINGLETON が優先されます。STV_EXPORTSTV_DEFAULT 可視性属性とと一緒に使用できますが、STV_EXPORT が優先されます。STV_SINGLETON または STV_EXPORT 可視性は、それ以外の可視性属性とは一緒に使用できません。そのような場合、リンク編集にとって致命的とみなされます。

ほかの可視性の属性は、リンク編集中、実行可能ファイルまたは共有オブジェクト内のシンボルの解決にはまったく影響をおよぼしません。このような解決は、結合タイプによって制御されます。いったんリンカーがその解決を選択すると、これらの属性は次の 2 つの必要条件を課します。どちらの必要条件も、リンクされるコード内の参照は、属性の利点を利用するために最適化されるという事実に基づくものです。

シンボル値がセクション内の特定位置を参照すると、セクションインデックスメンバー st_shndx は、セクションヘッダーテーブルへのインデックスを保持します。再配置時にセクションが移動すると、シンボル値も変化します。シンボルへの参照はプログラム内の同じ位置を指し示し続けます。いくつかの特別なセクションインデックス値は、ほかのセマンティクスが付けられています。

SHN_ABS

このシンボルは、再配置が行われても変わらない絶対値を持ちます。

SHN_COMMON および SHN_AMD64_LCOMMON

このシンボルは、まだ割り当てられていない共通ブロックを示します。シンボル値は、セクションの sh_addralign メンバーに類似した整列制約を与えます。リンカーは st_value の倍数のアドレスにシンボル記憶領域を割り当てます。シンボルのサイズは、必要なバイト数を示します。

SHN_UNDEF

このセクションテーブルインデックスは、シンボルが未定義であることを示します。リンカーがこのオブジェクトファイルを、示されたシンボルを定義するほかのオブジェクトファイルに結合すると、このシンボルに対するこのファイルの参照は定義に結び付けられます。

前述したとおり、インデックス 0 (STN_UNDEF) のシンボルテーブルエントリは予約されています。このエントリは次の値を保持します。

表 7-21 ELF シンボルテーブルエントリ: インデックス 0

名前
注意
st_name
0
名前が存在しない
st_value
0
値は 0
st_size
0
サイズが存在しない
st_info
0
種類はない。ローカル結合
st_other
0
st_shndx
SHN_UNDEF
セクションは存在しない

シンボル値

異なる複数のオブジェクトファイル型のシンボルテーブルエントリは、st_value メンバーに対してわずかに異なる解釈を持ちます。

シンボルテーブル値は、異なる種類のオブジェクトファイルでも似た意味を持ちますが、適切なプログラムはデータに効率的にアクセスできます。

シンボルテーブルのレイアウトと規則

シンボルテーブル内のシンボルは、次の順序で書き込まれます。

Oracle Solaris OS には、3 つの特別なシンボルテーブルがあります。

.symtab (SHT_SYMTAB)

このシンボルテーブルには、関連する ELF ファイルを示すあらゆるシンボルが入っています。このシンボルテーブルは、通常は割り当てることができないため、プロセスのメモリーイメージ内では使用できません。

ELIMINATE キーワードと一緒に mapfile を使用すると、.symtab から大域シンボルを削除できます。「シンボル削除」および 「SYMBOL_SCOPE/SYMBOL_VERSION 指令」を参照してください。リンカーの -z redlocsym オプションを使用して、ローカルシンボルを削除することもできます。

.dynsym (SHT_DYNSYM)

このテーブルには、.symtab テーブルのシンボルのうち、動的リンクをサポートするために必要なシンボルだけが入っています。このシンボルテーブルは、割り当てることができるため、プロセスのメモリーイメージ内で使用できます。

.dynsym テーブルは標準 NULL シンボルで始まり、そのあとに大域シンボルが続きます。STT_FILE シンボルは通常、このシンボルテーブルにはありません。STT_SECTION シンボルは、再配置エントリが必要とする場合に存在する可能性があります。

.SUNW_ldynsym (SHT_SUNW_LDYNSYM)

.dynsym テーブル内で見つかる情報を拡張する省略可能なシンボルテーブル。.SUNW_ldynsym テーブルには局所関数シンボルが含まれます。このシンボルテーブルは、割り当てることができるため、プロセスのメモリーイメージ内で使用できます。このセクションを追加することで、.symtab を割り当てることができないために、テーブルが使用できないまたはファイルから削除されたときでも、デバッガは実行時状況で正確なスタックトレースを行うことができます。また、このセクションは、dladdr(3C) が使用する追加シンボリック情報を実行時環境に提供します。

.SUNW_ldynsym テーブルが存在するには、.dynsym テーブルが存在している必要があります。.SUNW_ldynsym セクションと .dynsym セクションの両方があるときは、リンカーはそれらのデータ領域を並べて配置します (.SUNW_ldynsym が最初)。このように配置されることで、2 つのテーブルを大きな 1 つの連続したシンボルテーブルとして表示することができます。このシンボルテーブルは、すでに説明した標準レイアウト規則に従います。

.SUNW_ldynsym テーブルを削除するには、リンカーの -z noldynsym オプションを使用します。

シンボルソートセクション

並んで配置される .SUNW_ldynsym セクションと .dynsym セクションによって作成される動的なシンボルテーブルを使って、メモリーアドレスを対応するシンボルにマッピングできます。このマッピングを使って、特定のアドレスがどの関数または変数を表現するかを判断できます。ただし、シンボルテーブルを解析してマッピングを判断することは、シンボルがシンボルテーブルに書き込まれる順番が原因で、複雑な作業になります。「シンボルテーブルのレイアウトと規則」を参照してください。このレイアウトによって、アドレスをシンボル名に関連付ける作業は複雑になります。

これらの問題を解決するために、シンボルソートセクションを使用します。シンボルソートセクションは、Elf32_Word または Elf64_Word オブジェクトの配列です。この配列の各要素は、.SUNW_ldynsym.dynsym の結合シンボルテーブルへのインデックスです。この配列の要素は、参照されるシンボルがソート順に提供されるようにソートされます。関数または変数を表現するシンボルのみが取り込まれます。ソート配列に関連付けられたシンボルは、 -S オプション付きで elfdump(1) に使用することで表示できます。

通常のシンボルとスレッド固有領域シンボルを一緒にソートすることはできません。通常のシンボルの値は、そのシンボルが参照している関数または変数のアドレスです。スレッド固有領域シンボルの値は、変数のスレッドオフセットです。したがって、通常のシンボルとスレッド固有領域シンボルでは、異なる 2 つのソートセクションが使用されます。

.SUNW_dynsymsort

SHT_SUNW_SYMSORT タイプのセクション。.SUNW_ldynsym.dynsym の結合シンボルテーブル内の通常のシンボルへのインデックスが含まれます (アドレスでソート) 。変数または関数を表現しないシンボルは取り込まれません。

.SUNW_dyntlssort

SHT_SUNW_TLSSORT タイプのセクション。.SUNW_ldynsym.dynsym の結合シンボルテーブル内の TLS シンボルへのインデックスが含まれます (オフセットでソート) 。このセクションは、オブジェクトファイルに TLS シンボルが含まれる場合にだけ作成されます。

リンカーは、ソートセクションがどのシンボルを参照するかを選択するために、次の規則を記載順に使用します。

これらの規則によって、コンパイラとリンカーが自動的に生成するシンボルは除外されます。選択されるシンボルは、ユーザーに関係するものです。ただし、次の 2 つの場合には、選択処理を改善するために手動による介入が必要になる場合があります。

mapfile のキーワード DYNSORT および NODYNSORT により、シンボルをきめ細かく選択できます。「SYMBOL_SCOPE/SYMBOL_VERSION 指令」を参照してください。

DYNSORT

ソートセクションに含める必要があるシンボルを指定します。シンボルタイプは STT_FUNCSTT_OBJECTSTT_COMMON、または STT_TLS である必要があります。

NODYNSORT

ソートセクションに含める必要があるシンボルを指定します。

たとえば、あるオブジェクトのシンボルテーブル定義が次のようになっているとします。

$ elfdump -sN.symtab foo.so.1 | egrep "foo$|bar$"
      [37]  0x000004b0 0x0000001c  FUNC GLOB  D   0 .text      bar
      [38]  0x000004b0 0x0000001c  FUNC WEAK  D   0 .text      foo

シンボル foobar は別名ペアを表現しています。デフォルトでは、ソートされた配列を作成するときに、シンボル foo だけが表現されます。

$ cc -o foo.so.1 -G foo.c
$ elfdump -S foo.so.1 | egrep "foo$|bar$"
      [13]  0x000004b0 0x0000001c  FUNC WEAK  D   0 .text      foo

リンカーによって同じ項目を参照する大域シンボルとウィークシンボルが検出された場合は、通常はウィークシンボルが選択されます。ウィークシンボル foo に関連付けられたので、シンボル bar はソートされた配列から除外されます。

次の mapfile を実行すると、シンボル bar がソートされた配列内で表現されています。シンボル foo は表示されません。

$ cat mapfile
{
    global:
        bar = DYNSORT;
        foo = NODYNSORT;
};
$ cc -M mapfile -o foo.so.2 -Kpic -G foo.c
$ elfdump -S foo.so.2 | egrep "foo$|bar$"
      [13]  0x000004b0 0x0000001c  FUNC GLOB  D   0 .text      bar

.SUNW_dynsymsort セクションと .SUNW_dyntlssort セクションには、.SUNW_ldynsym セクションの存在が必要です。したがって、- z noldynsym オプションを使用すると、すべてのソートセクションが作成されなくなります。

レジスタシンボル

SPARC アーキテクチャーは、レジスタシンボル (大域レジスタを初期化するシンボル) をサポートします。レジスタシンボルに対するシンボルテーブルエントリには、次の値が入ります。

表 7-22 SPARC: ELF シンボルテーブルエントリ: レジスタシンボル

フィールド
意味
st_name
シンボル名文字列テーブルへのインデックス。または 0 (スク ラッチレジスタ)。
st_value
レジスタ番号。整数レジスタの割り当てについては、ABI マニュアルを参照してください。
st_size
未使用 (0)。
st_info
結合は標準的には STB_GLOBAL です。種類は STT_SPARC_REGISTER でなければなりません。
st_other
未使用 (0)。
st_shndx
このオブジェクトがこのレジスタシンボルを初期化する場合は、SHN_ABS。それ以外の場合は、SHN_UNDEF

定義済みの SPARC 用レジスタ値を、次に示します。

表 7-23 SPARC: ELF レジスタ番号

名前
意味
STO_SPARC_REGISTER_G2
0x2
%g2
STO_SPARC_REGISTER_G3
0x3
%g3

特定の大域レジスタのエントリが存在しないことは、その特定の大域レジスタがオブジェクトで使用されないことを意味します。

Syminfo テーブルセクション

syminfo セクションには、Elf32_Syminfo 型または Elf64_Syminfo 型の複数のエントリが存在します。.SUNW_syminfo セクションには、関連付けられているシンボルテーブル (sh_link) のエントリごとに 1 つのエントリが存在します。

このセクションがオブジェクトに存在している場合、関連付けられているシンボルテーブルからシンボルインデックスを取り出し、このシンボルインデックスを使ってこのセクションに存在する対応する Elf32_Syminfo エントリまたは Elf64_Syminfo エントリを見つけることで、追加シンボル情報を見つけます。関連付けられているシンボルテーブルと、Syminfo テーブルには、必ず同じ数のエントリが存在します。

インデックス 0 は、Syminfo テーブルの現バージョン (SYMINFO_CURRENT) を格納するために使用されます。シンボルテーブルエントリ 0 は必ず UNDEF シンボルテーブルエントリ用に予約されるので、矛盾は発生しません。

Syminfo エントリの形式は、次のとおりです。sys/link.h を参照してください。

typedef struct {
        Elf32_Half      si_boundto;
        Elf32_Half      si_flags;
} Elf32_Syminfo;

typedef struct {
        Elf64_Half      si_boundto;
        Elf64_Half      si_flags;
} Elf64_Syminfo;
si_boundto

.dynamic セクションのエントリへのインデックスで、sh_info フィールドにより示され、Syminfo フラグを増加させます。たとえば、DT_NEEDED エントリは、Syminfo エントリに関連付けられた動的オブジェクトを示します。次の表に示すエントリは、si_boundto に対して予約されています。

名前
意味
SYMINFO_BT_SELF
0xffff
自己に結びつけられるシンボル。
SYMINFO_BT_PARENT
0xfffe
親に結びつけられるシンボル。親は、この動的オブジェクトの読み込みを発生させる最初のオブジェクトです。
SYMINFO_BT_NONE
0xfffd
シンボルに特別なシンボル結合は含まれません。
SYMINFO_BT_EXTERN
0xfffc
シンボル定義は外部です。
si_flags

このビットフィールドでは、次の表に示すフラグを設定できます。

名前
意味
SYMINFO_FLG_DIRECT
0x01
シンボル参照は、定義を含むオブジェクトへ直接関連付けられます。
SYMINFO_FLG_FILTER
0x02
シンボル定義は標準フィルタとして機能します。
SYMINFO_FLG_COPY
0x04
シンボル定義はコピー再配置の結果です。
SYMINFO_FLG_LAZYLOAD
0x08
遅延読み込みの必要があるオブジェクトに対するシンボル参照です。
SYMINFO_FLG_DIRECTBIND
0x10
シンボル参照は定義に直接結合される必要があります。
SYMINFO_FLG_NOEXTDIRECT
0x20
外部参照はこのシンボル定義に直接結合できません。
SYMINFO_FLG_AUXILIARY
0x40
シンボル定義は補助フィルタとして機能します。
SYMINFO_FLG_INTERPOSE
0x80
シンボル定義は割り込み処理として機能します。この属性は動的実行可能ファイルにのみ適用できます。
SYMINFO_FLG_CAP
0x100
シンボルは機能と関連付けられています。
SYMINFO_FLG_DEFERRED
0x200
シンボルを BIND_NOW 再配置に含めません。

バージョン管理セクション

リンカーで作成されるオブジェクトには、2 つの型のバージョン情報が存在できます。

これらのセクションを形成する構造体は、sys/link.h 内で定義されています。バージョン情報が存在するセクションには、.SUNW_version という名前が付けられます。

バージョン定義セクション

このセクションは、タイプ SHT_SUNW_verdef によって定義されます。このセクションが存在する場合、SHT_SUNW_versym セクションも存在しなければなりません。これら 2 つの構造体は、ファイル内にシンボルとバージョン定義の関連付けを提供します。「バージョン定義の作成」を参照してください。このセクションの要素の構造体は、次のとおりです。

typedef struct {
        Elf32_Half      vd_version;
        Elf32_Half      vd_flags;
        Elf32_Half      vd_ndx;
        Elf32_Half      vd_cnt;
        Elf32_Word      vd_hash;
        Elf32_Word      vd_aux;
        Elf32_Word      vd_next;
} Elf32_Verdef;
 
typedef struct {
        Elf32_Word      vda_name;
        Elf32_Word      vda_next;
} Elf32_Verdaux;

typedef struct {
        Elf64_Half      vd_version;
        Elf64_Half      vd_flags;
        Elf64_Half      vd_ndx;
        Elf64_Half      vd_cnt;
        Elf64_Word      vd_hash;
        Elf64_Word      vd_aux;
        Elf64_Word      vd_next;
} Elf64_Verdef;
 
typedef struct {
        Elf64_Word      vda_name;
        Elf64_Word      vda_next;
} Elf64_Verdaux;
vd_version

このメンバーは、構造体のバージョンを示します (次の表を参照)。

名前
意味
VER_DEF_NONE
0
無効バージョン。
VER_DEF_CURRENT
>=1
現在のバージョン。

値 1 は最初のセクション形式を示し、拡張した場合は、より大きい番号の新しいバージョンが必要です。VER_DEF_CURRENT の値は、現在のバージョン番号を示すために必要に応じて変化します。

vd_flags

このメンバーは、バージョン定義に固有の情報を保持します (次の表を参照)。

名前
意味
VER_FLG_BASE
0x1
ファイルのバージョン定義。
VER_FLG_WEAK
0x2
ウィークバージョン識別子。

基本バージョン定義は、バージョン定義またはシンボルの自動短縮簡約がファイルに適用されている場合、必ず存在します。基本バージョンは、ファイルの予約されたシンボルに対してデフォルトのバージョンを与えます。ウィークバージョン定義には、関連付けられているシンボルは存在しません。「ウィークバージョン定義の作成」を参照してください。

vd_ndx

バージョンインデックス。各バージョン定義には、SHT_SUNW_versym エントリを適切なバージョン定義に関連付ける一意のインデックスが存在します。

vd_cnt

Elf32_Verdaux 配列の要素数。

vd_hash

バージョン定義名のハッシュ値。この値は、「ハッシュテーブルセクション」に記述されているのと同じハッシング機能により生成されます。

vd_aux

この Elf32_Verdef エントリの先頭からバージョン定義名の Elf32_Verdaux 配列までのバイトオフセット。配列の先頭要素は存在しなければなりません。この要素はこの構造体が定義するバージョン定義文字列を指し示します。追加要素は存在可能です。要素の番号は vd_cnt 値で示されます。これらの要素は、このバージョン定義の依存関係を表します。これらの依存関係の各々は、独自のバージョン定義構造体を持っています。

vd_next

この Elf32_Verdef 構造体の先頭から次の Elf32_Verdef エントリまでのバイトオフセット。

vda_name

ヌル文字で終わる文字列への文字列テーブルオフセットで、バージョン定義名を指定します。

vda_next

この Elf32_Verdaux エントリの先頭から次の Elf32_Verdaux エントリまでのバイトオフセット。

バージョン依存セクション

バージョン依存セクションは、タイプ SHT_SUNW_verneed によって定義されます。このセクションは、ファイルの動的依存性から要求されるバージョン定義を示すことで、ファイルの動的依存性要求を補足します。依存性にバージョン定義が存在する場合のみ、記録がこのセクションにおいて行われます。このセクションの要素の構造体は、次のとおりです。

typedef struct {
        Elf32_Half      vn_version;
        Elf32_Half      vn_cnt;
        Elf32_Word      vn_file;
        Elf32_Word      vn_aux;
        Elf32_Word      vn_next;
} Elf32_Verneed;
 
typedef struct {
        Elf32_Word      vna_hash;
        Elf32_Half      vna_flags;
        Elf32_Half      vna_other;
        Elf32_Word      vna_name;
        Elf32_Word      vna_next;
} Elf32_Vernaux;

typedef struct {
        Elf64_Half      vn_version;
        Elf64_Half      vn_cnt;
        Elf64_Word      vn_file;
        Elf64_Word      vn_aux;
        Elf64_Word      vn_next;
} Elf64_Verneed;
 
typedef struct {
        Elf64_Word      vna_hash;
        Elf64_Half      vna_flags;
        Elf64_Half      vna_other;
        Elf64_Word      vna_name;
        Elf64_Word      vna_next;
} Elf64_Vernaux;
vn_version

このメンバーは、構造体のバージョンを示します (次の表を参照)。

名前
意味
VER_NEED_NONE
0
無効バージョン。
VER_NEED_CURRENT
>=1
現在のバージョン。

値 1 は最初のセクション形式を示し、拡張した場合は、より大きい番号の新しいバージョンが必要です。VER_NEED_CURRENT の値は、現在のバージョン番号を示すために必要に応じて変化します。

vn_cnt

Elf32_Vernaux 配列の要素数。

vn_file

ヌル文字で終わっている文字列への文字列テーブルオフセットで、バージョン依存性のファイル名を指定します。この名前は、ファイル内に存在する .dynamic 依存性のどれかに一致します。「動的セクション」を参照してください。

vn_aux

この Elf32_Verneed エントリの先頭から、関連付けられているファイル依存性から要求されるバージョン定義の Elf32_Vernaux 配列までのバイトオフセット。少なくとも 1 つのバージョン依存性が存在する必要があります。追加バージョン依存性は存在することができ、また番号は vn_cnt 値で示されます。

vn_next

この Elf32_Verneed エントリの先頭から次の Elf32_Verneed エントリまでのバイトオフセット。

vna_hash

バージョン依存性の名前のハッシュ値。この値は、「ハッシュテーブルセクション」に記述されているのと同じハッシング機能により生成されます。

vna_flags

バージョン依存性に固有の情報 (次の表を参照)。

名前
意味
VER_FLG_WEAK
0x2
ウィークバージョン識別子。
VER_FLG_INFO
0x4
SHT_SUNW_versym 参照は情報提供のために存在しており、実行時に検証の必要はありません。

ウィークバージョン依存性は、ウィークバージョン定義への最初の結び付きを示します。

vna_other

ゼロでない場合、この依存関係バージョンに割り当てられたバージョンインデックス。SHT_SUNW_versym 内でこのインデックスを使用して、大域シンボル参照をこのバージョンに割り当てます。

Solaris 10 のリリースまで、バージョンシンボルインデックスは依存関係バージョンに割り当てられていませんでした。これらのオブジェクトでは、vna_other の値は 0 です。

vna_name

ヌル文字で終わる文字列への文字列テーブルオフセット。バージョン依存性の名前を与えます。

vna_next

この Elf32_Vernaux エントリの先頭から次の Elf32_Vernaux エントリまでのバイトオフセット。

バージョンシンボルセクション

バージョンシンボルセクションは、タイプ SHT_SUNW_versym によって定義されます。このセクションは、次の構造を持つ要素配列で構成されます。

typedef Elf32_Half      Elf32_Versym;
typedef Elf64_Half      Elf64_Versym;

配列の要素数は、関連付けられているシンボルテーブルに存在するシンボルテーブルエントリ数に等しくなければなりません。この値は、セクションの sh_link 値で決定されます。配列の各要素には 1 つのインデックスが存在し、このインデックスは次の表に示す値をとることができます。

表 7-24 ELF バージョン依存インデックス

名前
意味
VER_NDX_LOCAL
0
シンボルにローカル適用範囲が存在します。
VER_NDX_GLOBAL
1
シンボルに大域適用範囲が存在し、ベースバージョン定義に割り当てられています。
>1
シンボルは大域適用範囲を持ち、ユーザー定義のバージョン定義 SHT_SUNW_verdef、またはバージョン依存関係 SHT_SUNW_verneed に割り当てられています。

シンボルが、予約された特別なインデックス 0 に割り当てられる場合があります。このインデックスには次のいずれかの理由のために割り当てられます。

オブジェクトで定義されたバージョンは、1 から始まるバージョンインデックスが割り当てられ、バージョンごとに 1 増加します。インデックス 1 は最初の大域バージョンに予約されています。オブジェクトに SHT_SUNW_verdef バージョン定義セクションがない場合、そのオブジェクトで定義されたすべての大域シンボルはインデックス 1 を受け取ります。オブジェクトにバージョン定義セクションがない場合、VER_NDX_GLOBAL は前述の最初のバージョンを参照するだけです。

ほかの SHT_SUNW_verneed 依存関係からオブジェクトが要求したバージョンには、最終のバージョン定義インデックスの後に 1 を加えた値から始まるバージョンインデックスが割り当てられます。これらのインデックスもバージョンごとに 1 増加します。インデックス 1 は常に VER_NDX_GLOBAL に予約されているため、依存関係のバージョンが取り得るの最初のインデックスは 2 となります。

Solaris 10 リリースまで、バージョンインデックスは SHT_SUNW_verneed 依存関係バージョンに割り当てられていませんでした。このようなオブジェクトでは、いずれのシンボル参照のバージョンインデックスも、バージョン管理情報が該当のシンボルで使用できないことを表す 0 になります。