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

ドキュメントの情報

はじめに

パート I リンカーおよび実行時リンカーの使用

1.  Oracle Solaris リンカーの紹介

2.  リンカー

3.  実行時リンカー

4.  共有オブジェクト

5.  インタフェースおよびバージョン管理

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

パート II クイックリファレンス

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

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

パート III 詳細情報

9.  直接結合

10.  mapfile

11.  拡張性メカニズム

パート IV ELF アプリケーションバイナリインタフェース

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

ファイル形式

データ表現

ELF ヘッダー

ELF 識別

データの符号化

セクション

セクションのマージ

特殊セクション

「COMDAT」セクション

グループセクション

機能セクション

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

移動セクション

注釈セクション

再配置セクション

再配置計算

SPARC: 再配置

SPARC: 再配置型

64 ビット SPARC: 再配置型

x86: 再配置

32 ビット x86: 再配置型

x64: 再配置型

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

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

シンボル値

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

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

レジスタシンボル

Syminfo テーブルセクション

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

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

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

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

13.  プログラムの読み込みと動的リンク

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

パート V 付録

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

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

索引

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

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

シンボルの種類および結び付けられる属性。値と意味のリストを、表 12-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

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

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

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

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

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

表 12-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 フィールドで指定され、これにより、関連付けられた実体の一般的な分類が決定されます。

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

STT_LOOS - STT_HIOS

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

STT_LOPROC - STT_HIPROC

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

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

表 12-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) のシンボルテーブルエントリは予約されています。このエントリは次の値を保持します。

表 12-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 指令」を参照してください。

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

表 12-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 用レジスタ値を、次に示します。

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

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

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